一份简短且有立场的 Web 按钮可访问性清单
五条规则,帮助在上线前发现大多数按钮可访问性问题
目录
按钮可访问性建议的问题
大多数按钮可访问性指南分为两类:要么是没人会读的 40 页 WCAG 解读,要么只是含糊地建议“让按钮可访问”,却没有可执行步骤。当你要在周四交付一个功能时,这两种都帮不上忙。
这份清单覆盖了我们在生产环境中最常见的五类按钮可访问性失败。它不会让你成为 WCAG 专家,但能帮你发现那些真正影响用户的问题。
1. 用 button 元素来做按钮
如果它的行为像按钮,它就应该是一个 <button> 元素。不是带 onclick 的 <div>,不是带 role="button" 的 <span>,也不是带 href="#" 并调用 preventDefault 的 <a>。
<button> 元素天然提供键盘导航、焦点管理和屏幕阅读器播报。当你使用 <div> 时,你是在从零重建这一切——而且你一定会出错。
唯一的例外:如果该操作会导航到新页面或改变 URL,请使用 <a> 元素。链接和按钮在语义上不同。屏幕阅读器用户会按元素类型导航,他们期望按钮执行操作,链接进行导航。
2. 让命中目标至少达到 44×44 像素
WCAG 2.5.5(Level AAA)要求交互元素的最小目标尺寸为 44×44 CSS 像素。这说的不是视觉尺寸,而是可点击区域。
你可以让按钮在视觉上较小但具备足够的内边距,也可以用伪元素扩展命中目标。关键是不要让用户必须精确瞄准。
移动端用户、有运动障碍的人,以及任何在移动状态下使用设备的人,都会更容易点不中小目标。一个 24×24 像素的图标按钮也许看起来很清爽,但它是一次可用性失败。
3. 提供可见的焦点状态,不要只依赖浏览器默认样式
浏览器默认的焦点环总比没有好,但它在不同浏览器之间并不一致,并且在某些背景上常常不可见。你需要一个能在你的设计系统中生效的自定义焦点状态。
一个好的焦点指示器具备三个特点:
- 高对比度:相对于相邻颜色至少达到 3:1
- 可见偏移:不会被按钮自身的边框或背景遮住
- 形状一致:用户应能在整个界面中识别出它是焦点指示器
不要设置 outline: none 却不提供更好的替代方案。也不要把焦点状态做得过于微妙,以至于只有你在完美光线条件下才看得见。
4. 编写脱离上下文也能理解的按钮标签
屏幕阅读器用户常常通过在按钮之间跳转来浏览。当他们这样做时,听到的是一串没有周围上下文的按钮标签。
在这个列表里,一个标为“了解更多”的按钮毫无用处。“点击这里”或“提交”也是如此。标签应该描述操作:“下载可访问性清单”、“订阅更新”、“删除这条评论”。
如果你的设计需要较短的可视标签,可以使用 aria-label 提供描述性替代文本。但更好的方案是编写对所有人都有效的标签。
对于仅图标按钮,aria-label 是必需的。一个只有放大镜图标的按钮需要 aria-label="Search" 或等效文本。图标本身对屏幕阅读器不可访问。
5. 确保足够的颜色对比度
WCAG 2.1 要求普通文本的对比度至少为 4.5:1,大号文本(18pt 或 14pt 加粗)至少为 3:1。按钮标签通常属于普通文本。
白色按钮上的浅灰色文字不合格。浅蓝色背景上的淡蓝色文字也不合格。这些组合也许看起来精致,但它们会排除低视力、色盲用户,以及任何在强烈阳光下看屏幕的人。
在设计阶段就使用对比度检查工具,而不是上线之后才检查。在生产环境中修复对比度问题成本很高,因为它通常需要修改设计系统。
如果你正在使用图像处理工具,client-side processing 可以在生成可访问视觉资产时帮助保护隐私——尤其是在测试颜色组合或生成预览状态时。
这份清单没有覆盖什么
这份清单有意并不完整。它没有覆盖禁用状态语义、加载状态、错误处理,或拆分按钮、下拉触发器等复杂按钮模式。这些模式需要单独的指南。
它也没有覆盖何时使用按钮、何时使用其他交互元素这个更广泛的问题。为此,你需要理解语义化 HTML 和 accessibility tree——这些主题值得单独成文。
它覆盖的是低垂的果实:几乎每次代码评审都会出现、影响最多用户、并且在开发阶段最容易修复的错误。
如何把它整合到你的工作流中
可访问性清单只有成为开发流程的一部分时才有效,而不是事后再补上。可以这样做:
在设计中:在设计文件中添加焦点状态和命中目标标注。不要把这些留给开发者去猜。
在代码评审中:检查 <button> 元素、图标按钮上的 aria-label,以及焦点状态 CSS。这些都很容易快速发现。
在测试中:用键盘在界面中按 Tab 浏览。如果你无法到达某个按钮,或看不到焦点在哪里,你的用户也一样。
在文档中:把按钮可访问性要求写入组件库。让做正确的事比做错误的事更容易。
如果你正在调试生产问题,用于检查 HTTP headers 和 redirects 的工具可以帮助你理解辅助技术如何解释你的标记——尤其是在排查导航后的焦点管理问题时。
跳过这项工作的代价
不可访问的按钮不只是无法满足 WCAG 合规要求——它们会中断工作流。无法点击提交按钮的用户就无法完成表单。看不到焦点状态的用户就无法用键盘导航。无法区分按钮文字和背景的用户就无法阅读标签。
这些并不是边缘情况。全球约 15% 的人口有某种形式的残障,而临时性障碍(鼠标坏了、强烈阳光、抱着婴儿)最终会影响每个人。
好消息是,按钮可访问性大多是已经解决的问题。你不需要发明新模式,也不需要等待浏览器支持。你只需要正确使用平台,并测试你的工作。
关键要点
- 对按钮使用
<button>元素,对导航使用<a>元素——这种语义差异对辅助技术很重要 - 确保命中目标至少为 44×44 CSS 像素,以适应运动障碍用户和移动端用户
- 提供可见、高对比度、能贯穿整个设计系统的焦点状态
- 编写在单独朗读时也能理解的按钮标签,并为仅图标按钮使用
aria-label - 在设计阶段检查颜色对比度,而不是上线后再检查,以避免昂贵的返工
FAQ
Q: 如果我添加键盘处理程序,可以在 <div> 上使用 role="button" 吗?
A: 可以,但不应该。你需要手动处理 Enter、Space、焦点管理和禁用状态——而且你不可避免地会漏掉某些东西。<button> 元素默认就能正确完成这一切。请使用它。
Q: 像播放/暂停按钮这样会切换状态的按钮怎么办?
A: 使用 aria-pressed="true" 或 aria-pressed="false" 来表示当前状态。按钮标签也应反映点击后将发生的操作(播放时显示“暂停”,暂停时显示“播放”),而不是当前状态。屏幕阅读器用户需要知道按钮会做什么,而不是系统当前处于什么状态。
Q: 禁用按钮需要满足对比度要求吗?
A: WCAG 2.1 将禁用控件排除在对比度要求之外(1.4.3),但这存在争议。对比度差的禁用按钮对所有人来说都难以感知。如果你要显示一个禁用按钮,就让它可读。更好的做法是隐藏它,或解释为什么它被禁用。
Q: 不使用屏幕阅读器,如何测试按钮可访问性?
A: 使用键盘。用 Tab 遍历界面,确认你可以到达每个按钮、看得见焦点在哪里,并能用 Enter 或 Space 激活按钮。这能发现大多数问题。若要进行更深入的测试,可使用 Chrome 或 Firefox DevTools 中的 accessibility inspector 检查计算后的角色和标签。
Q: aria-label 和 aria-labelledby 有什么区别?
A: aria-label 直接提供一个文本字符串。aria-labelledby 引用另一个元素的 ID,并将该元素的文本内容作为标签。当标签文本已经存在于 DOM 的其他位置时,使用 aria-labelledby。当你需要提供一个屏幕上不可见的标签时,使用 aria-label。
来源
- Web Content Accessibility Guidelines (WCAG) 2.1 — W3C
- Inclusive Components: Toggle Buttons — Heydon Pickering
- The ARIA Button Pattern — W3C ARIA Authoring Practices Guide
- WebAIM: Keyboard Accessibility — WebAIM


