关于 accessibility-testing
供 Agent 检查网页和组件是否符合 WCAG 2.1 AA 或 AAA。结合自动扫描、人工测试指引,并生成含代码修复建议的结构化报告。
主要功能
- 01WCAG 2.1 AA 与 AAA 审查
- 02自动扫描指引
- 03键盘导航检查
- 04屏幕阅读器测试指引
- 05含代码修复的结构化报告
适用场景
- 01发布前审查网页
- 02查找用户流程中的键盘操作问题
- 03修复 React 或 Vue 组件的无障碍问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ seb1n/ awesome-ai-agent-skills --skill accessibility-testing安装后在 Claude Code 中输入/accessibility-testing确认已加载。
详细介绍
无障碍测试
此技能可让 Agent 根据《Web 内容无障碍指南》(WCAG)2.1 的 AA 和 AAA 符合性等级,对网页和组件进行全面的无障碍审查。Agent 会根据四项原则——可感知、可操作、可理解、稳健——识别违规问题,并生成包含具体代码修复方案的结构化合规报告。审查范围包括自动化检查(颜色对比度、缺少替代文本、ARIA 误用)、半自动化检查(键盘导航流程、焦点管理)和手动检查指南(屏幕阅读器播报、认知负荷)。
工作流
-
定义审查范围和符合性目标:确定要审查的页面、组件或用户流程,以及目标是 WCAG 2.1 AA(最常见的法律要求)还是 AAA(最高符合性等级)。确定需要考虑的辅助技术:屏幕阅读器(Windows 上的 NVDA、macOS/iOS 上的 VoiceOver、Android 上的 TalkBack)、仅使用键盘进行导航,以及放大工具。
-
运行自动化扫描:使用 axe-core 或 Lighthouse 执行自动化无障碍分析。这些工具可自动检测约 30-40% 的 WCAG 违规问题,包括缺少 alt 属性、颜色对比度不足、缺少表单标签、ID 重复、ARIA 角色无效,以及缺少文档语言。记录每项违规,并附上其 WCAG 成功准则参考(例如,1.4.3 最低对比度)、严重级别(严重、高、中、低)、受影响的 HTML 元素和 CSS 选择器路径。
-
执行键盘导航测试:手动仅使用 Tab、Shift+Tab、Enter、Space、Escape 和方向键逐一测试所有交互流程。确认焦点顺序与视觉顺序一致、焦点指示器清晰可见(至少 2px 的轮廓,且对比度为 3:1)、模态对话框能正确限制焦点,并且不存在键盘陷阱。记录键盘用户无法完成、但鼠标用户可以完成的任何流程。
-
使用屏幕阅读器进行测试:至少使用一种屏幕阅读器浏览页面,确认所有内容都能正确播报。确认图像具有有意义的替代文本(装饰性图像使用
alt="")、标题构成合理的层级结构(不跳过层级)、存在地标(<nav>、<main>、<aside>),且动态内容更新会通过aria-live区域播报。 -
生成合规报告:按 WCAG 原则和成功准则组织结构化报告。每项违规都应包括:成功准则编号和名称、严重级别、受影响元素的 HTML 代码片段、未通过的原因说明,以及具体的代码修复方案。报告还应包含按原则统计通过/失败数量的汇总表,以及总体符合性声明。
-
提供修复代码:针对每项违规,提供具体的修复前后代码片段,展示准确的修复方式。按组件或页面区域对修复方案分组,以便开发者系统地逐项处理,而不必一次只修复一个元素。
用法
向 Agent 提供 URL、HTML 代码块或 React/Vue 组件。指定目标符合性等级(AA 或 AAA)以及任何辅助技术要求。Agent 将审查内容并返回包含代码修复方案的结构化报告。
示例
示例 1:WCAG 合规性审计报告
用户请求:“审计此登录表单是否符合 WCAG 2.1 AA 标准。”
<div class="login">
<img src="logo.png">
<input type="text" placeholder="Username">
<input type="password" placeholder="Password">
<div class="btn" onclick="login()">Sign In</div>
<p style="color: #aaa; font-size: 12px;">Forgot your password?</p>
</div>
Agent 响应 — 无障碍审计报告:
| # | 标准 | 严重程度 | 元素 | 问题 |
|---|---|---|---|---|
| 1 | 1.1.1 非文本内容 | 严重 | <img src="logo.png"> | 图片没有 alt 属性。屏幕阅读器无法描述图片。 |
| 2 | 1.3.1 信息和关系 | 严重 | <input placeholder="Username"> | 输入框没有关联的 <label>。占位符文本不能替代标签。 |
| 3 | 1.3.1 信息和关系 | 严重 | <input placeholder="Password"> | 与上面相同的标签问题。 |
| 4 | 1.4.3 对比度(最低) | 较严重 | <p style="color: #aaa"> | 白色背景上的文本颜色 #aaa 对比度为 2.32:1。此字号的文本要求达到 4.5:1。 |
| 5 | 2.1.1 键盘 | 严重 | <div class="btn" onclick> | <div> 无法通过键盘获得焦点。用户无法通过 Tab 键定位或激活此按钮。 |
| 6 | 4.1.2 名称、角色、值 | 严重 | <div class="btn" onclick> | 元素没有语义角色。屏幕阅读器会将其读作普通文本,而不是按钮。 |
修复方案 — 修正后的代码:
<form class="login" onsubmit="login(event)">
<img src="logo.png" alt="Acme Corp logo">
<label for="username">Username</label>
<input id="username" type="text" autocomplete="username" required>
<label for="password">Password</label>
<input id="password" type="password" autocomplete="current-password" required>
<button type="submit" class="btn">Sign In</button>
<a href="/forgot-password" style="color: #595959; font-size: 14px;">
Forgot your password?
</a>
</form>
所做更改:为图片添加 alt,将只有占位符的输入框替换为明确的 <label> 元素,将 <div> 替换为语义化的 <button>,将链接颜色从 #aaa(2.32:1)改为 #595959(7.0:1),用 <form> 元素包裹表单以正确处理提交,并添加 autocomplete 属性。
示例 2:修复 React 组件
用户请求:“修复此 React 通知组件中的无障碍问题。”
修复前(无法访问):
function Notification({ message, onClose }) {
return (
<div className="notification">
<span>{message}</span>
<span className="close-x" onClick={onClose}>✕</span>
</div>
);
}
修复后(可访问):
function Notification({ message, onClose }) {
return (
<div role="alert" aria-live="assertive" className="notification">
<p>{message}</p>
<button
type="button"
onClick={onClose}
aria-label="Dismiss notification"
className="close-btn"
>
✕
</button>
</div>
);
}
已应用的修复:(1) 添加 role="alert" 和 aria-live="assertive",让屏幕阅读器在通知出现时立即播报。(2) 将 <span onClick> 替换为 <button>,使其可通过键盘获得焦点,并被播报为交互控件。(3) 添加 aria-label="Dismiss notification",因为单独的“✕”字符无法向屏幕阅读器用户传达按钮的用途。(4) 将内部的 <span> 改为 <p>,以符合文本语义。
最佳实践
- 先运行自动化工具,但绝不要只依赖它们:axe-core 可以检测出约 30-40% 的 WCAG 问题。其余 60-70% 需要通过手动键盘测试、屏幕阅读器验证和认知层面的审查来发现。
- 使用真实屏幕阅读器进行测试,而不只是使用 ARIA 验证器:元素可能具有正确的 ARIA 标记,但仍会产生令人困惑的播报。VoiceOver 和 NVDA 有时会对相同标记作出不同解读。
- 先修复严重和较严重问题,再处理中等问题:优先处理会完全阻碍访问的问题(缺少键盘操作能力、功能性图片没有替代文本),而不是外观问题(装饰元素的对比度略有不足)。
- 优先使用语义化 HTML,而不是直接使用 ARIA:
<button>不需要role="button"。<nav>不需要role="navigation"。当语义化 HTML 不足以满足需求时,ARIA 才是补救工具,而不是替代品。 - 在 CI 工作流中加入无障碍检查:在自动化测试中运行 axe-core 或 pa11y,以便在新问题进入生产环境之前将其发现。对于严重问题,应让构建失败。
- 记录无障碍设计决策:当组件有意偏离某项指南时(例如,自定义组合框模式),应记录其理由,以及用于维持同等可访问性的替代方案。
边缘情况
- 带客户端路由的单页应用:页面导航不会触发浏览器页面加载,因此屏幕阅读器不会收到新内容的通知。使用
aria-live="polite"区域播报路由变更,或以编程方式将焦点移至新页面的<h1>。 - 初次渲染后加载的动态内容:页面加载后通过 JavaScript 注入的内容对屏幕阅读器不可见,除非将其放在
aria-live区域中,或明确管理焦点。对于 Toast 通知,使用aria-live="assertive";对于信息流更新,使用aria-live="polite"。 - 复杂数据表格:带有合并单元格、多层表头或可排序列的表格需要显式设置
scope、headers和aria-sort属性。测试屏幕阅读器用户能否理解每个数据单元格对应的表头。 - 自定义交互式控件(滑块、日期选择器、组合框):这些控件没有对应的原生 HTML 元素。请严格遵循 WAI-ARIA Authoring Practices 1.2 中的模式,并实现其中为每种控件类型指定的完整键盘交互模型。
- 第三方嵌入内容(iframe、控件):你无法修复第三方 iframe 内的无障碍问题。请记录该问题,为
<iframe>添加描述性title属性,并在嵌入内容对用户流程至关重要时提供无障碍替代方案。