tabindex="0"无法解决卡片流焦点遮挡,真正需调整dom顺序、css溢出控制和js聚焦后滚动;tabindex="-1"才是动态焦点接管入口,且必须配合scrollintoview。

tabindex="0" 不能解决卡片流组件的焦点遮挡问题,真正要动的是 DOM 顺序、CSS 溢出控制和 JS 聚焦后滚动;tabindex="-1" 才是接管动态焦点的入口,但必须配 scrollIntoView。
为什么给卡片加 tabindex="0" 后焦点“看不见”或“跳不进去”
常见现象:卡片用 display: grid 或 overflow: hidden 包裹内容,用户按 Tab 键焦点进了卡片,但光标没显示、内容被截断、甚至焦点卡在空白处。
- 焦点确实进入了元素(
document.activeElement可验证),但视觉上不可见——因为卡片容器设置了overflow: hidden或父级有transform/clip-path,浏览器聚焦了,却没自动滚动定位 - 卡片内部有原生可聚焦子元素(如
button或input),但外层卡片也加了tabindex="0",导致 Tab 流重复停顿:一次停在外层 div,再按一次才到内部 button - 卡片是 React/Vue 动态渲染的,DOM 插入顺序和视觉网格顺序不一致,
tabindex="0"按源码顺序走,结果焦点从右下角卡片开始,而非左上角
tabindex="-1" 是卡片展开/悬停时聚焦的唯一可靠方式
当鼠标悬停或点击某张卡片触发详情浮层、编辑面板、悬浮工具栏时,焦点必须立刻落到新内容上——不能靠用户再按一次 Tab。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 目标元素(如浮层里的第一个
input)必须提前设tabindex="-1",否则.focus()在非原生元素上会静默失败(尤其移动端 Safari) - 不要给整个浮层容器设
tabindex="-1",否则焦点落在空 div 上,用户 Tab 仍会跳出组件 - 聚焦后必须立即调用
element.scrollIntoView({ block: 'nearest', inline: 'nearest' }),否则元素被overflow: hidden或 sticky 导航栏遮挡 - 若浮层是异步加载(如 API 获取详情后渲染),需确保 DOM 已挂载完成再执行
.focus(),可用requestAnimationFrame或setTimeout(() => ..., 0)
多层级卡片嵌套时 tabindex 的误用陷阱
卡片里嵌卡片(比如“项目列表 → 任务卡片 → 子任务折叠区”),容易层层加 tabindex="0",结果键盘用户每层都得按两次 Tab 才能往下走。
- 只对有明确交互意图的最外层卡片容器加
tabindex="0",例如整张卡片可点击跳转详情 —— 此时需同步加role="link"或role="button",并监听keydown响应 Enter/Space - 卡片内部的子操作项(如“编辑”按钮、“删除”图标)保持原生可聚焦性,不用额外设
tabindex;若用div实现,则每个子项单独设tabindex="0"+role+keydown,不要依赖外层卡片的 tabindex - 折叠区域展开后,其内部首个可操作元素(如第一个
textarea)设tabindex="-1",展开逻辑里调.focus(),而不是让外层卡片再次参与 Tab 流 - 绝对避免给任意一层卡片设正整数
tabindex(如tabindex="1"),它会把所有卡片拉到 Tab 流最前,且多个同值时仍按 DOM 插入顺序排,动态渲染下完全不可控
复杂点不在 tabindex 数值本身,而在 DOM 是否贴近语义流、JS 是否在状态切换瞬间精准聚焦、以及 scrollIntoView 是否被漏掉——这三个环节任一缺失,键盘用户就会卡在“看得见却摸不到”的地方。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










