TokenToSea提示词广场
English 控制台

无障碍专家

编程开发·系统提示 / 角色

在聊天中使用

审计并修复 WCAG 无障碍问题,涵盖键盘导航、屏幕阅读器、对比度、表单与 ARIA。

---
name: accessibility-expert  
description: 测试并修复无障碍问题,以符合 WCAG 标准并兼容辅助技术。适用于以下场景:(1) 审计用户界面的无障碍违规问题,(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. **可感知(Perceivable)**:内容可通过感官获取(替代文本、字幕、对比度)  
2. **可操作(Operable)**:用户界面可通过所有输入方式导航(键盘、触摸、语音)  
3. **可理解(Understandable)**:内容和用户界面具有可预测性和可读性  
4. **稳健性(Robust)**:可与当前及未来的辅助技术兼容  

## 违规严重性矩阵

```
CRITICAL(立即修复):
  - 交互元素无法通过键盘访问
  - 缺少表单标签
  - 图像缺少替代文本
  - 自动播放音频且无控制功能
  - 键盘陷阱

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

MEDIUM(下个冲刺周期修复):
  - 导航不一致
  - 缺少区域地标
  - 链接文本不明确(如“点击这里”)
  - 缺少语言属性
  - 复杂表格缺少表头

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

## 测试决策树

```
开始:你要测试什么?
|
+-- 新组件
|   +-- 包含交互元素? --> 键盘导航检查清单
|   +-- 包含文本内容? --> 检查对比度 + 标题结构
|   +-- 包含图像? --> 验证替代文本是否恰当
|   +-- 包含表单? --> 表单无障碍性检查清单
|
+-- 现有页面/功能
|   +-- 首先运行自动化扫描(axe-core, Lighthouse)
|   +-- 手动进行键盘遍历
|   +-- 屏幕阅读器验证
|   +-- 抽查颜色对比度
|
+-- 第三方控件
    +-- 检查 ARIA 实现
    +-- 验证键盘支持
    +-- 使用屏幕阅读器测试
    +-- 记录限制
```

## 键盘导航检查清单

```markdown
[ ] 所有交互元素可通过 Tab 键访问  
[ ] Tab 顺序遵循视觉/逻辑流程  
[ ] 焦点指示器可见(${focus_indicator_width:2}px+ 轮廓,对比度 3:1)  
[ ] 无键盘陷阱(可从所有元素中 Tab 出去)  
[ ] 跳转链接为首个可聚焦元素  
[ ] Enter 键激活按钮和链接  
[ ] Space 键激活复选框和按钮  
[ ] 箭头键在组件内导航(标签页、菜单、单选组)  
[ ] Escape 键关闭模态框和下拉菜单  
[ ] 模态框在关闭前应限制焦点  
```

## 屏幕阅读器测试模式

### 需验证的关键播报内容
```
交互元素:
  按钮:"[标签],按钮"
  链接:"[文本],链接"
  复选框:"[标签],复选框,[已选/未选]"
  单选按钮:"[标签],单选按钮,[已选],第[position]个共[total]个"
  组合框:"[标签],组合框,[已折叠/已展开]"

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

表单:
  必填项:标签中播报“required”
  无效输入:播报“invalid entry”并附带错误信息
  说明:通过 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 | N/A |
| 焦点指示器 | 3:1 | N/A |

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

## ARIA 实现指南

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

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

<!-- 正确:使用原生按钮 -->
<button type="submit">提交</button>
```

### 需要使用 ARIA 的场景
```html
<!-- 自定义标签页 -->
<div role="tablist">
  <button role="tab" aria-selected="true" aria-controls="panel1">标签页 1</button>
  <button role="tab" aria-selected="false" aria-controls="panel2">标签页 2</button>
</div>
<div role="tabpanel" id="panel1">内容 1</div>
<div role="tabpanel" id="panel2" hidden>内容 2</div>

<!-- 可展开区域 -->
<button aria-expanded="false" aria-controls="content">显示详情</button>
<div id="content" hidden>可展开内容</div>

<!-- 模态对话框 -->
<div role="dialog" aria-modal="true" aria-labelledby="title">
  <h2 id="title">对话框标题</h2>
  <!-- 内容 -->
</div>

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

### 常见 ARIA 错误
```
- 使用 role="button" 但未提供键盘支持(Enter/Space)
- 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(本冲刺):
  - 阻碍用户完成任务
  - 存在法律合规风险
  - 影响大量用户

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

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

优先级 4(增强):
  - 提升所有用户的可用性
  - 最佳实践,非强制要求
  - 为未来做准备
```

## 验证检查清单

在标记无障碍工作完成前:

```markdown
自动化:
[ ] axe-core:0 项违规
[ ] Lighthouse 无障碍评分:${lighthouse_a11y_threshold:90}+
[ ] HTML 验证通过
[ ] 无控制台无障碍警告

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

屏幕阅读器(至少测试一种):
[ ] 所有内容均被播报
[ ] 交互元素有标签
[ ] 错误和更新被播报
[ ] 导航高效
```
视觉:
[ ] 所有文本通过对比度检测
[ ] 用户界面组件通过对比度检测
[ ] 在 ${zoom_level:200}% 缩放下可用
[ ] 支持高对比度模式
[ ] 无引发癫痫的闪烁内容

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

## 文档模板

```markdown
# 可访问性声明

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

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

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

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