tabindex仅三种有效取值:-1(仅编程聚焦)、0(按dom顺序自然入流,最安全推荐)、正整数(破坏可访问性,应避免);非原生元素需同步加role、监听keydown事件并设置:focus-visible样式才真正可用。

tabindex 只有三种有效取值:-1、0、正整数;其中 0 是默认推荐值,-1 用于编程聚焦,正整数应避免使用。
tabindex="0" 怎么用才真正生效
给 div 或 span 加 tabindex="0",只是让它按 HTML 源码顺序自然进入 Tab 流——但它不会自动响应键盘操作,也不自带语义。
- 必须同步加
role="button"(或其他匹配语义的role),否则屏幕阅读器只读出“div”,无法理解功能 - 必须手动监听
keydown事件,判断event.key === 'Enter'或event.key === ' '(注意空格是字符串空格),并调用对应逻辑 - 必须加 CSS 的
:focus-visible或:focus样式,否则键盘用户看不到焦点在哪 - 原生可聚焦元素(如
button、a[href]、input)默认已有等效tabindex="0",无需重复设置
tabindex="-1" 不是隐藏开关,而是编程聚焦入口
设为 -1 后,元素无法通过 Tab 键到达,但能被 .focus() 主动聚焦——这是模态框、下拉菜单、折叠面板等动态组件的核心操作点。
- 模态框打开时,应立即对第一个可操作元素(如确认按钮)调用
.focus(),前提是它有tabindex="-1" - Accordion 展开后,焦点要移到新暴露的首项,而不是留在触发按钮上
-
tabindex="-1"不等于视觉隐藏:仅设它,元素仍可能被 Tab 到(比如用opacity: 0或position: absolute; left: -9999px隐藏时),此时需配合inert属性或显式移除tabindex - 移动端 Safari 有特殊限制:未触发过用户手势前,
.focus()对非原生可聚焦元素可能静默失败
为什么不能用 tabindex="1"、"2" 这类正整数
浏览器只看是否大于 0,不严格按数值排序;多个正数时虽按升序排列,但极易导致焦点流断裂、维护混乱和辅助技术误读。
- 设了
tabindex="1"的div会跑到所有默认可聚焦元素(如button)前面,而后者实际被挤到最后,形成断层 - DOM 中插入新元素,整个正数序列需重算;SSR 渲染时客户端与服务端值不一致还会触发 hydration 警告
- 常见错误是给多个按钮都设
tabindex="1",结果只有第一个生效——浏览器只认最小正整数,其余被忽略 - 屏幕阅读器依赖 DOM 顺序理解上下文,强行插队会让线性导航逻辑崩溃
真正难的不是选对某个 tabindex 值,而是理解焦点流本质是线性、不可跳变的路径;任何试图用正整数“插队”的做法,都会在动态内容、组件复用或 SSR 场景下露出破绽。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











