通用
难度:入门
无障碍测试超能力
Accessibility Testing Superpower
对网络应用执行 WCAG 合规性审计和无障碍修复。适用于:1) 审计 UI 的 WCAG 2.1/2.2 合规性。
适用平台:
ChatGPTClaudeGemini
---
name: accessibility-testing-superpower
description: |
对 Web 应用程序执行 WCAG 合规性审计和可访问性修复。
使用场景:1) 审计 UI 的 WCAG 2.1/2.2 合规性 2) 修复屏幕阅读器或键盘导航问题 3) 正确实现 ARIA 模式 4) 审查颜色对比度和视觉可访问性 5) 创建可访问的表单或交互式组件
---
# 可访问性测试工作流
## 配置
- **WCAG 等级**: ${wcag_level:AA}
- **被测组件**: ${component_name:Page}
- **合规标准**: ${compliance_standard:WCAG 2.1}
- **最低 Lighthouse 分数**: ${lighthouse_score:90}
- **主要屏幕阅读器**: ${screen_reader:NVDA}
- **测试框架**: ${test_framework:jest-axe}
## 审计决策树
```
收到可访问性请求
|
+-- 新组件/页面?
| +-- 首先运行自动化扫描 (axe-core, Lighthouse)
| +-- 键盘导航测试
| +-- 屏幕阅读器播报检查
| +-- 颜色对比度验证
|
+-- 现有违规待修复?
| +-- 识别 WCAG 成功准则
| +-- 检查语义化 HTML 是否能解决
| +-- 仅当 HTML 不足时才应用 ARIA
| +-- 使用辅助技术验证修复
|
+-- 合规性审计?
+-- 自动化扫描 (捕获约 30% 的问题)
+-- 手动测试清单
+-- 按严重程度记录违规
+-- 制定修复路线图
```
## WCAG 快速参考
### 严重性分类
| 严重性 | 影响 | 示例 | 修复时间线 |
|----------|--------|----------|--------------|
| 关键 | 完全阻碍访问 | 无键盘焦点,空按钮,功能性图片缺少 alt | 立即 |
| 严重 | 主要障碍 | 对比度差,缺少表单标签,无跳过链接 | 本冲刺内 |
| 中等 | 困难但可用 | 导航不一致,错误消息不清晰 | 下一版本 |
| 次要 | 不便 | 冗余 alt 文本,次要标题顺序问题 | 待办事项 |
### 常见违规和修复
**缺少可访问名称**
```html
<!-- 违规 -->
<button><svg>...</svg></button>
<!-- 修复:aria-label -->
<button aria-label="关闭对话框"><svg>...</svg></button>
<!-- 修复:视觉隐藏文本 -->
<button><span class="sr-only">关闭对话框</span><svg>...</svg></button>
```
**表单标签关联**
```html
<!-- 违规 -->
<label>电子邮件</label>
<input type="email">
<!-- 修复:显式关联 -->
<label for="email">电子邮件</label>
<input type="email" id="email">
<!-- 修复:隐式关联 -->
<label>电子邮件 <input type="email"></label>
```
**颜色对比度失败**
```
最低对比度 (WCAG ${wcag_level:AA}):
- 普通文本 (<${large_text_size:18}px 或 <${bold_text_size:14}px 粗体): ${contrast_ratio_normal:4.5}:1
- 大文本 (>=${large_text_size:18}px 或 >=${bold_text_size:14}px 粗体): ${contrast_ratio_large:3}:1
- UI 组件和图形: 3:1
工具: WebAIM Contrast Checker, 浏览器 DevTools
```
**焦点可见性**
```css
/* 绝不要在没有替代方案的情况下这样做 */
:focus { outline: none; }
/* 正确的自定义焦点 */
:focus-visible {
outline: ${focus_outline_width:2}px solid ${focus_outline_color:#005fcc};
outline-offset: ${focus_outline_offset:2}px;
}
```
## ARIA 决策框架
```
需要向辅助技术传达信息吗?
|
+-- 语义化 HTML 能做到吗?
| +-- 是:使用 HTML (<button>, <nav>, <main>, <article>)
| +-- 否:继续使用 ARIA
|
+-- 需要哪种 ARIA?
+-- 角色 (Role): 这个元素是什么? (role="dialog", role="tab")
+-- 状态 (State): 什么条件? (aria-expanded, aria-checked)
+-- 属性 (Property): 什么关系? (aria-labelledby, aria-describedby)
+-- 实时区域 (Live region): 动态内容? (aria-live="${aria_live_mode:polite}")
```
### 常见小部件的 ARIA 模式
**展开/折叠 (Disclosure)**
```html
<button aria-expanded="false" aria-controls="content-1">
显示详情
</button>
<div id="content-1" hidden>
内容在此
</div>
```
**选项卡界面**
```html
<div role="tablist" aria-label="${component_name:设置}">
<button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">
通用
</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">
隐私
</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">...</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>...</div>
```
**模态对话框**
```html
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
<h2 id="dialog-title">确认操作</h2>
<p>您确定要继续吗?</p>
<button>取消</button>
<button>确认</button>
</div>
```
## 键盘导航清单
```
[ ] 所有交互元素都可以通过 Tab 键聚焦
[ ] 焦点顺序与视觉/逻辑顺序一致
[ ] 所有元素上焦点可见
[ ] 无键盘陷阱 (始终可以通过 Tab 键退出)
[ ] 跳过链接作为第一个可聚焦元素
[ ] Escape 键关闭模态框/下拉菜单
[ ] 方向键在小部件内导航 (选项卡、菜单、网格)
[ ] Enter/Space 键激活按钮和链接
[ ] 自定义快捷键已文档化且可配置
```
### 焦点管理模式
**模态焦点陷阱**
```javascript
// 模态框打开时:
// 1. 保存之前聚焦的元素
// 2. 将焦点移至模态框内第一个可聚焦元素
// 3. 将 Tab 键操作限制在模态框边界内
// 模态框关闭时:
// 1. 将焦点返回到保存的元素
```
**动态内容**
```javascript
// 添加内容后:
// - 通过 aria-live 区域播报,或
// - 将焦点移至新内容的标题
// 移除内容后:
// - 将焦点移至逻辑上的下一个元素
// - 绝不要将焦点留在已移除的元素上
```
## 屏幕阅读器测试
### 播报验证
| 元素 | 应播报 |
|---------|-----------------|
| 按钮 | 角色 + 名称 + 状态 ("提交按钮") |
| 链接 | 名称 + "链接" ("主页链接") |
| 图片 | Alt 文本 或 "装饰性" (跳过) |
| 标题 | 级别 + 文本 ("标题级别 2, 关于我们") |
| 表单字段 | 标签 + 类型 + 状态 + 说明 |
| 错误 | 错误消息 + 字段关联 |
### 测试命令 (快速参考)
**VoiceOver (macOS)**
- VO = Ctrl + Option
- VO + A: 阅读所有内容
- VO + 右/左: 导航元素
- VO + Cmd + H: 下一个标题
- VO + Cmd + J: 下一个表单控件
**${screen_reader:NVDA} (Windows)**
- NVDA + 下: 阅读所有内容
- Tab: 下一个可聚焦元素
- H: 下一个标题
- F: 下一个表单字段
- B: 下一个按钮
## 自动化测试集成
### 测试中的 axe-core
```javascript
// ${test_framework:jest-axe}
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('${component_name:组件} 可访问', async () => {
const { container } = render(<${component_name:MyComponent} />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
```
### Lighthouse CI 阈值
```javascript
// lighthouserc.js
module.exports = {
assertions: {
'categories:accessibility': ['error', { minScore: ${lighthouse_score:90} / 100 }],
},
};
```
## 修复优先级矩阵
```
影响 vs 工作量:
低工作量 高工作量
高影响 | 优先做 | 计划下一步 |
| alt 文本 | 重新设计 |
| 标签 | 导航重建 |
----------------|--------------|---------------|
低影响 | 快速获胜 | 待办事项 |
| 对比度 | 锦上添花|
| 调整 | 增强功能|
```
## 验证清单
在标记可访问性工作完成之前:
```
自动化测试:
[ ] axe-core 报告零违规
[ ] Lighthouse 可访问性 >= ${lighthouse_score:90}
[ ] HTML 验证器通过 (影响 AT 解析)
键盘测试:
[ ] 无需鼠标即可完成所有任务
[ ] 焦点始终可见
[ ] 逻辑 Tab 顺序
[ ] 无陷阱
屏幕阅读器测试:
[ ] 至少使用一个屏幕阅读器 (${screen_reader:NVDA}) 进行测试
[ ] 所有内容播报正确
[ ] 交互元素具有角色/状态
[ ] 动态更新已播报
视觉测试:
[ ] 对比度已验证 (${contr