Skip to content
返回质量保障

WCAG 检查清单

对照 WCAG 四原则审计应用: 可感知、可操作、可理解、稳健。

为什么

WCAG(Web 内容无障碍指南)是无障碍国际标准,在许多司法管辖区是法律——美国 ADA、欧盟 EAA(2025 生效)及 30+ 国等效法律。合规之外,无障碍是 15% 残疾人口的可用性: 用屏幕阅读器的盲用户、用键盘的运动障碍用户、用屏幕放大镜的低视力用户、带字幕的聋用户。键盘填不了的表单、无 alt 文本的图片、无标签的按钮——这些排斥用户并招诉讼。WCAG 检查清单是系统找和修这些障碍的方式,是对所有人工作的应用的基线。

何时使用

从设计阶段到每次发布。CI 跑自动检查、发布前手动检查、年度或重大重设计时全审计。

如何做

1. 跑自动检查作第一遍
   - axe-core(或 @axe-core/playwright)编程检查
   - Lighthouse 无障碍审计快速评分
   - React 中 eslint-plugin-jsx-a11y lint 时检查
   - 这些抓约 30% WCAG 问题——机械的(缺 alt、无标签)

2. 手动键盘测试(最重要的手动检查)
   - 放下鼠标,用 Tab、Shift+Tab、Enter、Space、Escape 导航整个应用
   - 能到每个交互元素吗?焦点顺序合理吗?
   - 焦点指示可见吗?能激活按钮和链接吗?
   - 能用 Escape 关模态吗?焦点返回触发器吗?

3. 屏幕阅读器测试(第二重要)
   - Windows 用 NVDA(免费)或 JAWS、Mac 用 VoiceOver、Android 用 TalkBack
   - 按标题(H 键)、表单(F)、链接(K)、区域(R)导航
   - 页有合理标题结构吗(一个 h1,然后 h2,然后 h3)?
   - 表单字段带标签宣读吗?错误宣读吗?
   - 动态变更宣读吗(toast、购物车更新、错误的 aria-live)?

4. 查 WCAG 四原则(POUR)
   - 可感知: 内容对所有感官可呈现(alt 文本、字幕、足够对比)
   - 可操作: 界面可由所有输入导航(键盘、无时间限、无陷阱)
   - 可理解: 内容和操作可理解(清晰语言、错误恢复)
   - 稳健: 内容与辅助技术工作(有效 HTML、ARIA 正确用)

5. 记录和追踪发现
   - 每个发现建工单带违反的 WCAG 标准(如"1.4.3 对比")
   - 按影响优先: A 级(必修)> AA(应修)> AAA(最好有)
   - 大多法律要求 AA 级——以 AA 为基线

示例

// 自动: Playwright 中 axe-core
import { expect } from "@playwright/test";
import AxeBuilder from "@axe-core/playwright";

test("首页无 WCAG 违规", async ({ page }) => {
  await page.goto("/");
  const results = await new AxeBuilder({ page })
    .withTags(["wcag2a", "wcag2aa"]) // A 级和 AA
    .analyze();
  expect(results.violations).toEqual([]);
});

// Lint: eslint-plugin-jsx-a11y 写时抓问题
// .eslintrc.json
{
  "extends": ["plugin:jsx-a11y/recommended"]
}
// 抓: 无 role 的 <div onClick>、无 alt 的 <img>、无 label 的 <input>

// 手动: 键盘测试清单
// 1. Tab 过页——每个交互元素可到吗?
// 2. 焦点指示可见吗(非 outline: none)?
// 3. 能开模态、交互、用 Escape 关吗?
// 4. 焦点返回开模态的按钮吗?
// 5. Tab 顺序合理吗(跟视觉顺序)?

// 屏幕阅读器: NVDA + Chrome
// 1. 按 H 按标题导航——结构合理吗?
// 2. 按 F 按表单导航——字段带标签宣读吗?
// 3. 带错误提交表单——错误宣读吗?
// 4. 加购物车——购物车更新宣读吗(aria-live)?

// 修: 加 alt 文本、标签和合理标题结构
// 前:
<div onClick={addToCart}>买</div>
<img src="/product.jpg" />

// 后:
<button onClick={addToCart} aria-label="加产品到购物车">买</button>
<img src="/product.jpg" alt="蓝色小工具,5cm x 5cm,金属" />

常见问题

  • ⚠只跑 axe-core 把零违规当"无障碍"——axe 抓机械问题(缺 alt、无标签)但漏语义的(标题顺序、链接文本、错误恢复),需手动审查。
  • ⚠为"保险"每元素加 aria-label——冗余标签覆盖可见文本使屏幕阅读器输出更坏非更好(aria-label 应补充非重复)。
  • ⚠用屏幕阅读器测一次觉太难放弃——屏幕阅读器熟练需练,但即使 30 分钟测试也揭示影响真实用户的主要障碍。
  • ⚠先设计视觉 UI"后加无障碍"——设计建好时标题结构、焦点顺序和对比已 baked in,追溯改远难于从一开始为 a11y 设计。

最佳实践

  • ✓自动检查(CI 中 axe、lint 中 jsx-a11y)配手动键盘和屏幕阅读器测试——自动抓 30%,手动抓影响真实用户的语义问题。
  • ✓从一开始为无障碍设计: 合理标题结构、足够对比、可见焦点指示、键盘可操作——追溯改比设计入难 10 倍。
  • ✓真实设备上用真实辅助技术(NVDA、VoiceOver)测——模拟器和仿真器不完全复制体验,真测试是屏幕阅读器用户能否完成任务。
  • ✓以 WCAG 2.1 AA 级为基线(大多司法管辖区法律要求)并每标准当检查清单项追踪带状态和负责人。