用途
该技能用于构建面向所有人的无障碍 Web 应用,覆盖使用屏幕阅读器、纯键盘导航、开关设备及其他辅助技术的用户群体。它涉及 WCAG 2.2 在 AA 与 AAA 级别的合规、正确的 ARIA 用法、焦点管理、颜色对比度、减少动效支持以及自动化测试集成。
适用场景包括:构建新的 UI 组件、审查现有界面的无障碍合规性、修复 a11y 审计发现的问题,或将自动化无障碍测试集成到 CI/CD 流水线中。
核心原则
- 语义化 HTML 优先:原生 HTML 元素(
<button>、<nav>、<dialog>)自带无障碍能力。ARIA 是语义不足时的修复工具,而非正确 HTML 的替代品。 - 键盘是基线:如果仅用键盘无法操作,那就是不可用。每个交互元素都必须可聚焦、可操作,并有可见的焦点指示。
- 使用真实辅助技术测试:自动化工具只能发现约 30% 的无障碍问题,其余需要借助屏幕阅读器(VoiceOver、NVDA)和纯键盘导航进行手动测试。
- 渐进增强:先构建无障碍版本,再叠加视觉增强。绝不要对辅助技术隐藏视力正常用户可见的内容。
- 不单独依赖颜色传达信息:颜色可以强化含义,但绝不能作为唯一指示。应配合图标、文本标签和图案。
主要能力(关键模式)
模式 1:可访问的模态对话框
适用于任何需要用户交互后才能返回主内容的覆盖层。实现要点:使用原生 <dialog> 元素配合 showModal(),它自动提供焦点陷阱、Escape 键处理和正确的 role="dialog" 语义。打开前保存当前焦点元素,关闭后恢复焦点。通过 aria-labelledby 和 aria-describedby 关联标题与描述。自定义模态实现几乎总会有焦点陷阱缺陷,使用原生元素可免费获得正确行为。
模式 2:带错误处理的可访问表单
适用于任何收集用户输入并校验的表单。要点:每个字段都有程序化标签;错误通过 role="alert" 播报;错误消息通过 aria-describedby 与输入框关联;提供表单级错误摘要,让键盘用户可直接跳转到问题字段。使用 .sr-only 类实现仅屏幕阅读器可见的文本。错误不能仅靠颜色,需配合图标或加粗边框。
模式 3:自定义组件的键盘导航
适用于构建不映射到原生 HTML 元素的自定义交互组件(标签页、菜单、列表框、组合框)。要点:遵循 WAI-ARIA Authoring Practices 的键盘交互模式。例如标签页使用方向键在标签间移动(而非 Tab 键),非活动标签设置 tabIndex={-1},使只有活动标签处于 Tab 顺序中,符合屏幕阅读器用户的心智模型。
模式 4:动态内容的实时区域
适用于内容在不刷新页面的情况下更新、且需要告知屏幕阅读器用户的场景(通知、搜索结果、加载状态)。要点:屏幕阅读器不会监视 DOM 的视觉变化,实时区域显式告知辅助技术播报新内容。非紧急更新(搜索结果、Toast)使用 aria-live="polite",紧急消息(错误、会话过期)使用 role="alert"。
模式 5:自动化无障碍测试
适用于每个项目,集成到 CI/CD 和开发工作流中。要点:使用 Jest + axe-core 进行组件测试,Playwright + axe 进行端到端测试,并在 GitHub Actions 中运行 axe 测试与 pa11y。自动化测试能一致且尽早地发现结构性问题(缺失标签、无效 ARIA、对比度失败)。在 CI 中自动捕获 30% 的问题,好过捕获 0% 并在上线后才发现。需结合手动测试实现完整覆盖。
颜色对比度速查
| 文本尺寸 | WCAG AA | WCAG AAA |
|---|---|---|
| 普通文本(< 18px / 14px 粗体) | 4.5:1 | 7:1 |
| 大文本(>= 18px / 14px 粗体) | 3:1 | 4.5:1 |
| UI 组件与图形对象 | 3:1 | 3:1 |
| 装饰性 / 禁用元素 | 无要求 | 无要求 |
ARIA 速查
| 需求 | 应使用 | 不应使用 |
|---|---|---|
| 输入框标签 | <label for="x"> 或 aria-labelledby |
仅用 placeholder 作标签 |
| 描述输入要求 | aria-describedby 指向提示文本 |
title 属性 |
| 隐藏装饰性内容 | aria-hidden="true" |
display: none(对所有人隐藏) |
| 标记必填字段 | aria-required="true" + required |
仅视觉星号 |
| 播报错误 | role="alert" 或 aria-live="assertive" |
仅改变文本颜色 |
| 可展开区域 | aria-expanded="true/false" |
自定义 data-open 属性 |
反模式
| 反模式 | 问题 | 更好做法 |
|---|---|---|
用 <div onclick> 代替 <button> |
无键盘访问、无角色、无焦点 | 可点击元素使用 <button> |
| 原生 HTML 可用时仍用 ARIA | 更复杂、更多 bug | 用 <nav> 而非 <div role="navigation"> |
tabindex="5"(正值) |
破坏自然 Tab 顺序 | 只用 tabindex="0" 或 tabindex="-1" |
aria-label 重复可见文本 |
屏幕阅读器读两遍 | 仅对不可见标签使用 aria-label |
隐藏焦点轮廓(outline: none) |
键盘用户失去位置感 | 改为样式化 :focus-visible |
页面加载时 autofocus |
使屏幕阅读器用户迷失方向 | 让用户自然导航 |
| 文本图片 | 无法缩放、无法翻译 | 使用真实文本配合 CSS 样式 |
检查清单
- 所有交互元素均可键盘访问(Tab、Enter、Space、Escape、方向键)
- 所有可聚焦元素都有可见焦点指示(
:focus-visible) - 所有图片都有描述性
alt文本(装饰性图片用alt="") - 表单输入都有关联的
<label>元素
(资料中检查清单在此处截断,后续条目暂未提供。)
限制
资料未提供该技能的具体安装方式、依赖版本、支持的框架范围、收费或价格信息,这些内容暂未提供。