标准 · ARIA

角色 控件

button

将元素标记为按钮 — 一个在激活时触发操作的控件。优先使用原生 HTML <button> 元素;仅在无法使用原生元素时,才在 <div> 或 <span> 上使用 role="button"。

何时使用

几乎从不需要 — 请使用原生 <button> 元素。原生元素会自动处理焦点管理、空格键和回车键激活、禁用状态以及表单提交语义。在 <div> 上使用 role="button" 意味着你必须自行重新实现所有这些功能,而大多数开发者并不会这样做。

role="button" 的合理使用场景非常有限:

  • 受第三方设计系统限制,该系统提供的是非按钮组件。
  • <button> 不可用的环境中编写内容(例如某些遗留 CMS 模板)。
  • 在规划重构的同时,短期内将某个 <div> 升级以满足无障碍要求。

如果确实使用了 role="button",还必须:

  • 通过 tabindex="0" 使该元素可获得焦点。
  • keydown 事件同时绑定 EnterSpace(对 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>