角色 控件
button
将元素标记为按钮 — 一个在激活时触发操作的控件。优先使用原生 HTML <button> 元素;仅在无法使用原生元素时,才在 <div> 或 <span> 上使用 role="button"。
何时使用
几乎从不需要 — 请使用原生 <button> 元素。原生元素会自动处理焦点管理、空格键和回车键激活、禁用状态以及表单提交语义。在 <div> 上使用 role="button" 意味着你必须自行重新实现所有这些功能,而大多数开发者并不会这样做。
role="button" 的合理使用场景非常有限:
- 受第三方设计系统限制,该系统提供的是非按钮组件。
- 在
<button>不可用的环境中编写内容(例如某些遗留 CMS 模板)。 - 在规划重构的同时,短期内将某个
<div>升级以满足无障碍要求。
如果确实使用了 role="button",还必须:
- 通过
tabindex="0"使该元素可获得焦点。 - 为
keydown事件同时绑定Enter和Space(对 Space 使用event.preventDefault()以阻止页面滚动)。 - 通过
aria-disabled="true"自行管理禁用状态,并阻止点击处理器触发。
切换按钮
如果按钮是切换型按钮(静音/取消静音、播放/暂停、关注/取消关注),请将 aria-pressed 设置为 "true" 或 "false"。屏幕阅读器会连同标签一起播报其状态,例如:“静音,切换按钮,未按下”。
常见错误
<div onclick="…">提交</div>— 无法获得焦点,无法用键盘操作,没有角色。鼠标用户可以使用;其他人都无法使用。<a href="#" onclick="…">伪装成按钮。浏览器将其视为链接,屏幕阅读器将其宣告为链接,用户预期的是导航跳转。role="button"缺少tabindex="0"— 屏幕阅读器宣告”按钮”,但键盘无法到达该元素。- 自定义按钮只响应回车键,不响应空格键。
- 按钮没有可访问名称 — 缺少
aria-label的纯图标按钮是 axe-core 检测到的最常见错误之一。
示例
<!-- 推荐方式 -->
<button type="button" aria-pressed="false">Mute</button>
<!-- 仅在无法使用 <button> 时 -->
<div
role="button"
tabindex="0"
aria-pressed="false"
onclick="toggleMute()"
onkeydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); toggleMute(); }"
>
Mute
</div>