设 tabindex="0" 可使自定义元素(如 div、span)按 DOM 顺序加入键盘 Tab 导航流;tabindex="-1" 仅支持 JS 主动聚焦;正数 tabindex 易破坏焦点逻辑,应避免。

tabindex 怎么设才让键盘能走到自定义元素上
默认只有 <a>、<button>、<input> 这类原生可交互元素能被 Tab 键聚焦。想让 <div> 或 <span> 也进入键盘导航流,必须加 tabindex 属性。
关键不是随便加个数字:
-
tabindex="0"—— 最常用,元素按 DOM 顺序加入 Tab 流,不改变默认焦点顺序 -
tabindex="-1"—— 不能通过 Tab 进入,但可用 JavaScript 主动.focus()聚焦(比如模态框打开后自动聚焦标题) -
tabindex="1"及正数 —— 强制提前聚焦顺序,极易打乱逻辑流,无障碍实践中应避免
键盘操作没响应?检查事件监听是否覆盖了 keydown
仅靠 tabindex 不够,用户按 Enter 或 Space 时还得触发对应行为。别只监听 click —— 键盘用户不会“点击”,他们按键。
正确做法是同时绑定 keydown 并识别关键码:
- 对按钮类元素,监听
Enter(event.key === 'Enter')和Space(注意:Space需event.preventDefault()防止页面滚动) - 避免用
keyCode(已废弃),统一用event.key或event.code - 如果用了
role="button"却没处理键盘事件,屏幕阅读器会报“不可操作”,但用户实际按了没反应
element.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleClick();
}
});
导航跳转类链接(如锚点)为什么键盘按了没反应
常见陷阱:用 <div onclick="location.href='#about'">关于我</div> 模拟链接。这在键盘下完全失效 —— 它既不是 <a>,也没声明语义,更没处理 Space/Enter。
正确方案分两种场景:
- 真跳转到页面内锚点:直接用
<a href="#about">关于我</a>,浏览器原生支持所有键盘行为 - 需要 JS 控制的平滑滚动或 SPA 路由:保留
<a>标签,加role="link"(仅当 href 不是真实 URL 时),并手动监听keydown补齐Enter/Space - 绝对不要给非
<a>元素加href属性,那会让屏幕阅读器误读为链接但实际无法激活
focus-visible 伪类怎么用才不破坏鼠标用户的体验
默认浏览器会在所有获得焦点的元素上显示焦点轮廓(比如蓝色环),但鼠标用户觉得碍眼。直接 outline: none 是重大无障碍错误 —— 键盘用户将彻底失去焦点位置感知。
立即学习“前端免费学习笔记(深入)”;
现代解法是用 :focus-visible 精准控制:
- 只在真正由键盘触发聚焦时显示轮廓,鼠标点击/触摸后自动隐藏
- 需配合
outline: none+:focus-visible { outline: 2px solid #0066cc; } - 注意兼容性:Safari 直到 15.4 才支持,旧版需用 focus-visible polyfill
- 别用
:focus:not(:hover)替代 —— 触摸设备无 hover,且某些键盘操作(如 Shift+Tab)可能触发 hover
tabindex="0" 的卡片,或一处漏掉 Space 处理的自定义按钮,就足以让依赖键盘的用户卡在半路。










