先记住这个答案
表单控件大多天然可聚焦,通常不需要额外写 tabindex。0 让元素进入顺序 Tab,位置由 DOM 顺序决定;-1 可让脚本将焦点移到该元素,但用户按 Tab 通常不会走到它。正数会按从小到大排在 0 和自然可聚焦元素之前,常造成焦点突然跳跃,因此应优先调整 HTML 顺序。
0按文档顺序参与 Tab-1通常不参与顺序 Tab- 正数优先于
0 - 优先用 DOM 顺序表达操作流程
错误提示要能被脚本聚焦
提交表单后若顶部出现错误摘要,可给摘要设置 tabindex="-1",在脚本里把焦点移过去,让键盘用户立刻听到错误,再从摘要中的链接跳到具体字段。摘要无需占据日常 Tab 路径。
<div id="errors" tabindex="-1" role="alert">
请检查必填字段
</div>
<label>邮箱 <input type="email" name="email" required></label>
<button type="submit">保存</button>
<script>
// 校验失败后由脚本执行
document.querySelector('#errors').focus()
</script>焦点移动发生在校验失败时;平时按 Tab 会沿邮箱、按钮等可交互元素前进,而不是先停在这段提示上。
如果把摘要设为 tabindex="1",它会在页面其他自然焦点元素前面出现,表单稍有增删就容易打乱阅读顺序。
视觉顺序不等于焦点顺序
设计稿可能用 Grid 把按钮视觉上移到最前面,DOM 里它仍排在输入框后。Tab 路径不会因为 CSS 位置改变就自动跟着走,键盘用户看到的前后关系可能与操作顺序不一致。
先让 DOM 顺序符合任务流程,再做视觉布局。若焦点需要被程序控制,例如打开对话框时聚焦标题或首个输入,使用合适的焦点管理;不要靠大量正数 tabindex 修补结构。
默认可聚焦的 <button>、链接和输入框已经按 DOM 顺序参与 Tab 导航,通常不需要给它们重复写 tabindex="0"。真正危险的是用正数强行“修正”视觉顺序:用户按 Tab 会先跳完所有正数,再回到普通控件,和页面阅读顺序分离。错误提示若需要被脚本聚焦,可以给容器 tabindex="-1" 后调用 focus();它不会因此进入日常 Tab 链。焦点移动后还应让错误内容可被感知,而不是只改变边框颜色。
容易答错的地方
- 给每个字段编号 1、2、3
- 正数会抢在自然顺序之前,插入或删除字段时维护成本高;更好的办法是按正确顺序写 DOM。
- 把
tabindex="-1"当作彻底无法聚焦 - 它通常只退出顺序 Tab,脚本调用
focus()仍可将焦点移入。
面试官还会怎么问?
普通 <button> 需要写 tabindex="0" 吗?
通常不需要。按钮本来就是可聚焦控件,按 DOM 顺序进入 Tab。
禁用按钮还能靠 tabindex 聚焦吗?
原生 disabled 控件不能通过普通焦点交互恢复;tabindex 不应被用来绕开禁用语义。
CSS order 改变 Tab 顺序吗?
不会。视觉排序与 DOM 焦点顺序分离,交互流程应在结构层解决。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。