先记住这个答案
原生按钮、链接和表单控件本来就会进入键盘焦点顺序。需要让一个非原生元素参与顺序 Tab 时可设 tabindex="0",它按 DOM 位置排列;设 -1 时,脚本可调用 focus(),但通常不会由连续按 Tab 走到。正数会排在自然焦点项之前,随着页面动态变化很容易跳来跳去,通常应改 DOM 顺序。
0按 DOM 顺序参与 Tab-1可由脚本聚焦- 正数先于自然顺序
- 优先调整 DOM 而非编号焦点
错误摘要适合程序聚焦
表单提交失败时,顶部错误摘要要被读屏及时读到,但不需要让每次 Tab 导航都停在上面。给它 tabindex="-1",失败时移动焦点即可。
<div id="error-summary" tabindex="-1">
请检查标红的字段
</div>
<button type="submit">保存</button>
<script>
// 校验失败时调用
document.querySelector('#error-summary').focus()
</script>脚本调用 focus() 后,用户可以从错误摘要了解问题;正常使用时按 Tab 仍主要走交互控件。负值不是“完全不能聚焦”,而是退出顺序焦点导航。
错误摘要获得焦点后,视觉焦点也应清晰可见,尤其要让键盘用户知道页面跳到了哪里。错误处理完成后通常让用户继续按自然顺序进入第一个需要修改的字段;不要在每次输入时反复抢焦点,否则读屏还没读完提示就被打断。
如果给每个字段写 tabindex="1"、2、3,后面插入新字段就要重新编号。页面其他组件还可能使用正数,局部编号无法保证全页顺序。
焦点路径应跟操作流程一致
CSS 可以把按钮视觉上挪到输入框之前,Tab 路径却仍按 DOM 中先后顺序走。鼠标用户看到的排列与键盘用户的操作顺序不一致,会增加误操作。
先让 HTML 结构体现任务流程,默认焦点顺序就会较自然。对话框打开、错误发生等特殊时刻再用程序移动焦点,而不是持续靠正数 tabindex 修补页面结构。
这里还要分清“能被脚本聚焦”和“具有正确交互语义”。给普通 <div> 加 tabindex="0",它虽然能进入 Tab 顺序,却不会自动变成按钮:按 Enter、空格是否能操作、读屏如何称呼,都需要另外处理。能用原生 <button> 的场景应直接用按钮,省掉键盘事件与角色补丁。
tabindex="-1" 也不是让内容对读屏不可见。它只影响顺序焦点导航;读屏用户仍可能通过阅读命令遇到这段内容。若需求是隐藏内容,要用适合该状态的隐藏方式,不能靠负数 tabindex 解决。
容易答错的地方
- 认为
-1表示脚本也不能聚焦 - 它通常只移出顺序 Tab,
focus()仍可使用。 - 认为 CSS 视觉重排会同步焦点顺序
- 焦点路径主要看 DOM 与
tabindex,不是屏幕坐标。
面试官还会怎么问?
按钮需要写 tabindex="0" 吗?
通常不需要,原生按钮已经可以按自然顺序聚焦。
什么时候用正数?
绝大多数页面不需要。正数打乱全局顺序,优先调整 DOM 结构。
给普通段落加 tabindex="0" 合适吗?
只有用户确实需要在键盘导航中停留时才加,例如交互区域;不要把所有文字都塞进 Tab 路径。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。