← 返回提示词库
通用 #专业 #简短 难度:入门

无障碍专家

Accessibility Expert

测试并修复无障碍问题,以符合 WCAG 标准和辅助技术兼容性。适用于 (1) 审计 UI 的无障碍违规问题。

适用平台: ChatGPTClaudeGemini
---
name: accessibility-expert
description: 测试并修复可访问性问题,以符合 WCAG 标准和辅助技术兼容性。在以下情况下使用:(1) 审计 UI 中的可访问性违规,(2) 实现键盘导航或屏幕阅读器支持,(3) 修复颜色对比度或焦点指示器问题,(4) 确保表单可访问性和错误处理,(5) 创建 ARIA 实现。
---

# 可访问性测试与修复

## 配置

- **WCAG 等级**: ${wcag_level:AA}
- **目标组件**: ${component_name:Application}
- **合规标准**: ${compliance_standard:WCAG 2.1}
- **测试范围**: ${testing_scope:full-audit}
- **屏幕阅读器**: ${screen_reader:NVDA}

## WCAG 2.1 快速参考

### 合规等级
| 等级 | 要求 | 常见问题 |
|-------|-------------|---------------|
| A | 最低基线 | 缺少替代文本,无键盘访问,缺少表单标签 |
| ${wcag_level:AA} | 标准目标 | 对比度 < 4.5:1,缺少焦点指示器,标题结构不佳 |
| AAA | 增强 | 对比度 < 7:1,手语,扩展音频描述 |

### 四项原则 (POUR)
1. **可感知**: 内容可被感官获取(替代文本、字幕、对比度)
2. **可操作**: UI 可通过所有输入方法导航(键盘、触摸、语音)
3. **可理解**: 内容和 UI 可预测且可读
4. **鲁棒**: 适用于当前和未来的辅助技术

## 违规严重性矩阵

```
严重 (立即修复):
  - 交互元素无键盘访问
  - 缺少表单标签
  - 无替代文本的图片
  - 无控件的自动播放音频
  - 键盘陷阱

高(发布前修复):
  - 对比度低于 ${min_contrast_ratio:4.5}:1(文本)或 3:1(大文本)
  - 缺少跳过链接
  - 标题层级不正确
  - 焦点不可见
  - 缺少错误识别

中(下个冲刺修复):
  - 导航不一致
  - 缺少地标
  - 链接文本不佳(“点击此处”)
  - 缺少语言属性
  - 没有标题的复杂表格

低(待办事项):
  - 时间调整
  - 查找内容的多种方式
  - 上下文相关帮助
```

## 测试决策树

```
开始:您正在测试什么?
|
+-- 新组件
|   +-- 有交互元素吗? --> 键盘导航清单
|   +-- 有文本内容吗? --> 检查对比度 + 标题结构
|   +-- 有图片吗? --> 验证 alt 文本的适当性
|   +-- 有表单吗? --> 表单可访问性清单
|
+-- 现有页面/功能
|   +-- 首先运行自动化扫描(axe-core, Lighthouse)
|   +-- 手动键盘遍历
|   +-- 屏幕阅读器验证
|   +-- 颜色对比度抽查
|
+-- 第三方小部件
    +-- 检查 ARIA 实现
    +-- 验证键盘支持
    +-- 使用屏幕阅读器测试
    +-- 记录限制
```

## 键盘导航清单

```markdown
[ ] 所有交互元素都可以通过 Tab 键访问
[ ] Tab 键顺序遵循视觉/逻辑流
[ ] 焦点指示器可见(${focus_indicator_width:2}px+ 轮廓,3:1 对比度)
[ ] 没有键盘陷阱(可以 Tab 键离开所有元素)
[ ] 跳过链接作为第一个可聚焦元素
[ ] Enter 键激活按钮和链接
[ ] Space 键激活复选框和按钮
[ ] 方向键在组件内导航(选项卡、菜单、单选组)
[ ] Escape 键关闭模态框和下拉菜单
[ ] 模态框在关闭前捕获焦点
```

## 屏幕阅读器测试模式

### 需要验证的重要公告
```
交互元素:
  按钮:"[标签], 按钮"
  链接:"[文本], 链接"
  复选框:"[标签], 复选框, [已选中/未选中]"
  单选按钮:"[标签], 单选按钮, [已选中], [位置] 共 [总数]"
  组合框:"[标签], 组合框, [已折叠/已展开]"

动态内容:
  加载中:在容器上使用 aria-busy="true"
  状态:对于非关键更新使用 role="status"
  警报:对于关键消息使用 role="alert"
  实时区域:aria-live="${aria_live_politeness:polite}"

表单:
  必填项:与标签一起宣布“必填”
  无效项:与错误消息一起宣布“无效输入”
  说明:通过 aria-describedby 与标签一起宣布
```

### 测试顺序
1. 使用 Tab 键浏览整个页面,听取公告
2. 测试标题导航(屏幕阅读器中的 H 键)
3. 测试地标导航(D 键 / 转子)
4. 测试表格(T 键,表格内的箭头键)
5. 测试表单(F 键,完成表单提交)
6. 测试动态内容更新(验证实时区域)

## 颜色对比度要求

| 文本类型 | 最小对比度 | 增强(AAA) |
|-----------|---------------|----------------|
| 常规文本(<${large_text_threshold:18}pt) | ${min_contrast_ratio:4.5}:1 | 7:1 |
| 大文本(>=${large_text_threshold:18}pt 或 14pt 粗体) | 3:1 | 4.5:1 |
| UI 组件和图形 | 3:1 | 不适用 |
| 焦点指示器 | 3:1 | 不适用 |

### 对比度检查流程
```
1. 识别所有前景/背景颜色对
2. 计算对比度:(L1 + 0.05) / (L2 + 0.05)
   其中 L1 = 较亮亮度,L2 = 较暗亮度
3. 常见检查失败项:
   - 占位符文本(通常太亮)
   - 禁用状态(豁免但考虑可用性)
   - 文本中的链接(必须与文本区分开)
   - 彩色背景上的错误/成功状态
   - 图像上的文本(使用叠加层或文本阴影)
```

## ARIA 实现指南

### ARIA 第一原则
尽可能使用原生 HTML 元素。ARIA 仅用于自定义小部件。

```html
<!-- 错误:在原生元素上使用 ARIA -->
<div role="button" tabindex="0">Submit</div>

<!-- 正确:原生按钮 -->
<button type="submit">Submit</button>
```

### 何时需要 ARIA
```html
<!-- 自定义选项卡 -->
<div role="tablist">
  <button role="tab" aria-selected="true" aria-controls="panel1">Tab 1</button>
  <button role="tab" aria-selected="false" aria-controls="panel2">Tab 2</button>
</div>
<div role="tabpanel" id="panel1">Content 1</div>
<div role="tabpanel" id="panel2" hidden>Content 2</div>

<!-- 可展开部分 -->
<button aria-expanded="false" aria-controls="content">Show details</button>
<div id="content" hidden>Expandable content</div>

<!-- 模态对话框 -->
<div role="dialog" aria-modal="true" aria-labelledby="title">
  <h2 id="title">Dialog Title</h2>
  <!-- content -->
</div>

<!-- 用于动态更新的实时区域 -->
<div aria-live="${aria_live_politeness:polite}" aria-atomic="true">
  <!-- 状态消息注入此处 -->
</div>
```

### 常见的 ARIA 错误
```
- role="button" 但无键盘支持(回车/空格)
- aria-label 重复可见文本
- aria-hidden="true" 用于可聚焦元素
- 披露按钮缺少 aria-expanded
- aria-controls 引用不正确
- 使用 aria-describedby 描述必要信息
```

## 表单可访问性模式

### 必需的表单结构
```html
<form>
  <!-- 明确的标签关联 -->
  <label for="email">电子邮件地址</label>
  <input type="email" id="email" name="email"
         aria-required="true"
         aria-describedby="email-hint email-error">
  <span id="email-hint">我们绝不会分享您的电子邮件</span>
  <span id="email-error" role="alert"></span>

  <!-- 组合相关字段 -->
  <fieldset>
    <legend>收货地址</legend>
    <!-- 地址字段 -->
  </fieldset>

  <!-- 清晰的提交按钮 -->
  <button type="submit">完成订单</button>
</form>
```

### 错误处理要求
```
1. 识别出错字段(高亮 + 图标)
2. 用文本描述错误(不只是颜色)
3. 将错误与字段关联(aria-describedby)
4. 向屏幕阅读器宣布错误(role="alert")
5. 提交失败时将焦点移至第一个错误
6. 尽可能提供更正建议
```

## 移动端可访问性清单

```markdown
触摸目标:
[ ] 最小 ${touch_target_size:44}x${touch_target_size:44} CSS 像素
[ ] 目标之间有足够的间距(${touch_target_spacing:8}px+)
[ ] 触摸操作不依赖于手势路径

手势:
[ ] 多指手势的替代方案
[ ] 基于路径手势(滑动)的替代方案
[ ] 基于动作的操作有替代方案

```

屏幕阅读器 (iOS/Android):
[ ] 图像和图标设置了 accessibilityLabel
[ ] 复杂交互设置了 accessibilityHint
[ ] accessibilityRole 与元素行为匹配
[ ] 焦点顺序遵循视觉布局
```

## 自动化测试集成

### 预提交钩子
```bash
#!/bin/bash
# 对更改的文件运行 axe-core
npx axe-core-cli --exit src/**/*.html

# 检查常见问题
grep -r "onClick.*div\|onClick.*span" src/ && \
  echo "警告:在非交互元素上存在点击处理程序" && exit 1
```

### CI 流水线检查
```yaml
accessibility-audit:
  script:
    - npx pa11y-ci --config .pa11yci.json
    - npx lighthouse --accessibility --output=json
  artifacts:
    paths:
      - accessibility-report.json
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
```

### 最低 CI 阈值
```
axe-core: 0 个严重违规,0 个主要违规
Lighthouse 可访问性: >= ${lighthouse_a11y_threshold:90}
pa11y: 0 个错误 (警告可接受)
```

## 修复优先级框架

```
优先级 1 (本 Sprint):
  - 阻碍用户任务完成
  - 法律合规风险
  - 影响大量用户

优先级 2 (下个 Sprint):
  - 显著降低用户体验
  - 自动化工具标记为错误
  - 违反 ${wcag_level:AA} 要求

优先级 3 (待办事项):
  - 轻微不便
  - 仅违反 AAA
  - 影响边缘情况

优先级 4 (增强):
  - 改善所有用户的可用性
  - 最佳实践,而非要求
  - 面向未来
```

## 验证清单

在标记可访问性工作完成之前:

```markdown
自动化:
[ ] axe-core: 0 个违规
[ ] Lighthouse 可访问性: ${lighthouse_a11y_threshold:90}+
[ ] HTML 验证通过
[ ] 无控制台可访问性警告

键盘:
[ ] 仅使用键盘完成所有任务
[ ] 焦点始终可见
[ ] Tab 键顺序符合逻辑
[ ] 无键盘陷阱

屏幕阅读器(至少测试一个):
[ ] 所有内容均可播报
[ ] 交互元素已标记
[ ] 错误和更新已播报
[ ] 导航高效

视觉:
[ ] 所有文本通过对比度检查
[ ] UI 组件通过对比度检查
[ ] 在 ${zoom_level:200}% 缩放下正常工作
[ ] 在高对比度模式下正常工作
[ ] 无引起癫痫发作的闪烁

表单:
[ ] 所有字段均已标记
[ ] 错误可识别
[ ] 必填字段已标明
[ ] 提供说明
```

## 文档模板

```markdown
# 可访问性声明

## 符合性状态
本[网站/应用程序] [完全/部分] 符合 ${compliance_standard:WCAG 2.1} ${wcag_level:AA} 级别。

## 已知限制
| 功能 | 问题 | 变通方法 | 时间线 |
|---------|-------|------------|----------|
| [功能] | [描述] | [替代方案] | [修复日期] |

## 已测试的辅助技术
- ${screen_reader:NVDA} [版本] 与 Firefox [版本]
- VoiceOver 与 Safari [版本]
- JAWS [版本] 与 Chrome [版本]

## 反馈
有关可访问性问题,请联系 [电子邮件]。
最后更新:[日期]
```