关于 awesome-accessibility-audit
用于依据 WCAG 审查 UI 和标记的只读 Skill,并报告具体修复建议。面向审查页面、组件、表单和交互流程的团队;结果包含位置、影响、严重程度和建议修改。
主要功能
- 01语义化 HTML 与结构审查
- 02键盘操作和焦点检查
- 03标签、名称、颜色与对比度检查
- 04动态内容与媒体审查
- 05WCAG 2.2 标准检查
- 06提供具体修复和严重程度
适用场景
- 01发布前审查页面
- 02审计表单、对话框或交互组件
- 03UI 变更后检查无障碍性
- 04整理结果并交给组件负责人
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ khasky/ awesome-agent-skills --skill awesome-accessibility-audit安装后在 Claude Code 中输入/awesome-accessibility-audit确认已加载。
附带文件evals/eval_queries.json
详细介绍
无障碍审查
检查 UI 和标记,找出无障碍问题,并针对每项问题提供具体修复方案,使其符合 WCAG,让所有用户都能感知、操作并理解界面。
只读:仅报告问题,并为每项问题提供可解决该问题的标记或属性更改,绝不应用更改。报告中的代码片段与其满足的标准并列展示,便于审查;静默地应用同一项修改则不然。请将报告交给负责相应组件的人员。
何时启用
- 用户提及“无障碍”“a11y”“WCAG”或“屏幕阅读器支持”
- 发布新页面或组件之前
- 审查表单、模态框或交互式 UI 时
- 影响交互或内容的设计或 UI 更改之后
工作流程
- 确定范围 — 要审查的页面、组件或流程(例如登录表单、报告表格、模态对话框)。
- 检查各个方面 — 语义化 HTML、键盘操作、标签和名称、颜色与对比度、动态内容、动效。使用下方的检查清单。
- 记录问题 — 位置(组件/文件或元素类型)、WCAG 标准或原则、问题、影响及建议的修复方案。严重程度:严重 / 高 / 中。
- 提供修复方案,但不要应用 — 尽可能在报告中给出代码片段或属性更改。若原生 HTML 和正确的 ARIA 已足够,应优先使用它们,而不是自定义控件。
- 建议后续步骤 — 推荐自动化工具(例如 axe、Lighthouse、pa11y;在 CI 中,对严重问题设置构建失败)和更全面的手动测试。自动化工具只能发现约 30–40% 的 WCAG 问题,其余需要手动检查。建议采用“流程 × 辅助技术”矩阵:对每个关键用户流程,分别测试纯键盘操作、屏幕阅读器(Mac/iOS 上的 VoiceOver、Windows 上的 NVDA、Android 上的 TalkBack)、200% 和 400% 缩放 / 重排(WCAG 1.4.10)、Windows 高对比度模式以及减少动态效果;相关时还要注明 Voice Control/Dragon 和 Switch Control。不要声称仅凭一次审查就能证明完全符合 WCAG。
- 对测试中的自动化断言:
axe-core配合.withTags(['wcag2a','wcag2aa'])可针对特定 WCAG 等级,并能在发现违规时使 CI 失败;Playwright 的page.ariaSnapshot()(1.59+)可断言对话框、菜单和复合控件的无障碍树,覆盖范围超出 axe/Lighthouse。 - 在多个视口上运行自动扫描(移动端和桌面端断点,而不只是默认视口):焦点被遮挡、目标重叠和重排违规可能随视口尺寸变化而出现或消失,因此只扫描单个视口会悄然漏报。
- 对测试中的自动化断言:
完成标准:已说明审查范围,已逐项检查下方的所有方面;每项问题都注明位置、WCAG 标准及修复方案;对于只有通过屏幕阅读器或第二个视口才能确认的内容,明确标注为未测试,而非想当然地认定。
重点领域与检查清单
1. 语义化 HTML 和结构
- 每个页面只有一个
<h1>;标题级别按顺序排列(不跳过 2 → 4)。 - 主内容前设有跳转链接,且为第一个可聚焦元素(WCAG 2.4.1 绕过区块)。
- 视口元数据不得禁用缩放:标记
user-scalable=no和maximum-scale=1(WCAG 1.4.4)。 - 每个页面都有描述主题或用途的
<title>,并且在 SPA 路由变化时更新(2.4.2 页面标题,A)。 - 使用
<html>上的lang属性设置页面语言(3.1.1,A);其他语言的段落应设置各自的lang属性(3.1.2 语言部分,AA)。 - 内容不应锁定为单一方向(通过 CSS 或清单锁定方向),除非方向是必要的(1.3.4 方向,AA)。
- 重排:在宽度为 320 CSS px 时(1280px 视口放大 400%),内容无需二维滚动;数据表、地图及其他需要双向滚动的类似内容除外(1.4.10,AA)。
- 文本间距:应用 1.5 倍行高、2 倍段落间距、0.12em 字母间距和 0.16em 单词间距后,不得出现裁切、重叠或消失的内容;标记固定高度的文本容器和文本上的
overflow: hidden(1.4.12,AA)。 - 适当使用地标:
<main>、<nav>、<aside>、<footer>。 - 列表使用
<ul>/<ol>/<li>;表格在适用时使用<th>、scope和标题。 - 按钮使用
<button>或<input type="submit">;链接使用<a href="...">。不得在没有角色、键盘操作和焦点管理的情况下,将<div onclick>用于操作。 - 表单控件使用正确的类型并进行分组(分组使用
<fieldset>、<legend>)。
2. 键盘
- 所有交互元素都可聚焦(除非通过模态框管理,否则按钮/链接不得设置
tabindex="-1")。 - 焦点顺序符合逻辑(与视觉顺序一致或经过明确管理)。
- 提供可见的焦点指示器(轮廓或自定义样式);不得使用
outline: none移除指示器而不提供替代方案。优先使用:focus-visible(鼠标点击时不显示焦点环)和:focus-within(用于复合控件)。 - 不得造成键盘陷阱:用户可以通过 Tab 键离开模态框和菜单;在预期情况下按 Escape 可关闭。
- 自定义小部件(标签页、折叠面板、菜单)支持键盘操作(按 Enter/空格键激活,适用时支持方向键)。
- 悬停或聚焦时显示的内容(工具提示、弹出框、子菜单)必须可在不移动指针的情况下关闭(按 Escape);指针可以移到内容上而不使其消失;内容应持续显示,直到被关闭或不再相关(1.4.13,AA)。仅可通过悬停访问的功能也必须提供键盘和触摸操作方式。
3. 标签和名称
- 每个表单输入控件都有可见的
<label>或aria-label;标签与控件相关联(例如使用for/id或将控件包在标签中)。 - 输入控件具有正确的
type/inputmode和autocomplete属性(WCAG 1.3.5 识别输入用途)。 - 表单错误信息显示在对应字段旁边,并通过
aria-describedby与字段关联(否则屏幕阅读器在字段获得焦点时不会读出错误信息)。提交时,将焦点移至第一个错误;对于较长的表单,在顶部添加可通过键盘聚焦的错误摘要,并链接到每个出错字段(GOV.UK 模式)。 - 提交出错时保留用户输入,不要清空(减少重新输入的负担;参见 3.3.7)。在失去焦点时验证,而不是每次按键时都验证。
- 任何情况下都不得阻止粘贴(
onPaste+preventDefault是反模式),不只是密码字段。 - 按钮和链接应有清晰且唯一的名称(文本内容或
aria-label)。不得使用缺少上下文的“点击此处”或“阅读更多”。 - 名称包含标签:控件的无障碍名称应包含其可见文本,最好以该文本开头,让语音控制用户可以说出屏幕上看到的内容(2.5.3,A)。若
aria-label用不同文字替代可见文本,则不符合要求。 - 图像:有意义的图像使用描述内容的
alt;装饰性图像使用alt=""或role="presentation"。装饰性图标(内联 SVG、图标字体)设置aria-hidden="true"。 - iframe 和嵌入内容具有
title或aria-label。
4. 颜色和对比度
- 文本符合对比度要求(例如,普通文本为 4.5:1,大号文本为 3:1,UI 组件为 3:1)。请对照背景检查。(较新的设计系统可能使用 APCA,这是一种计划用于 WCAG 3.0 的感知模型——如果项目以 APCA 为目标,请注明;除非另有说明,否则仍按 WCAG 2.2 对比度要求审核。)
- 信息不能仅通过颜色传达(例如,必填字段、错误、状态)。还应使用图标、文本或图案。
- 焦点指示器清晰可见,不能仅依赖颜色变化。
5. 动态内容和焦点
- 出现或更新的内容(例如,toast、实时结果)会被播报:仅在紧急中断(错误、需要采取操作的 toast)时使用
aria-live="assertive";Feed 更新和结果数量使用aria-live="polite"。 - SPA 路由切换对屏幕阅读器保持静默:通过
aria-live="polite"区域播报新页面,或将焦点移至新页面的<h1>。 - 模态框和对话框:打开时焦点移入模态框;焦点限制在模态框内;关闭时焦点返回触发控件;根据模式将焦点置于第一个可聚焦元素或明确使用
autoFocus。 - 状态会清晰传达:展开/折叠(
aria-expanded)、已选中(aria-selected)、当前(aria-current)、已禁用(disabled或aria-disabled)。
6. 动效、媒体和时间
- 动画遵循
prefers-reduced-motion(减少或禁用);标记不遵循该设置的动效(2.3.3 交互触发的动画,AAA——报告为中等严重性)。 - 任何内容在任意一秒内闪烁都不超过三次(2.3.1 三次闪烁或低于阈值,A);检查动画 GIF、视频和画布特效。
- 任何与其他内容同时自动移动、闪烁或滚动超过 5 秒的内容(轮播、滚动字幕、自动播放的背景视频)都有暂停、停止或隐藏控件;自动更新的内容也必须提供这类控件(2.2.2,A)。
- 自动播放且时长超过 3 秒的音频可以暂停或停止,或可独立于系统音量控制其音量(1.4.2,A)。
- 带声音的预录视频提供字幕(1.2.2,A),并为纯视觉信息提供音频描述或文本替代方案(1.2.3,A;1.2.5 音频描述,AA);带声音的直播视频提供字幕(1.2.4,AA);纯音频和纯视频媒体提供文字稿或等效内容(1.2.1,A)。检查播放器控件本身是否可通过键盘操作且带有标签。
7. WCAG 2.2 新增要求(经常被遗漏)
- 2.4.11 焦点不被遮挡——粘性页眉/页脚不得遮挡获得焦点的元素(
scroll-margin-top有帮助)。 - 2.5.8 目标尺寸——交互目标至少为 24×24 CSS px,或较小目标之间留有足够间距。可见控件较小时,使用伪元素将点击区域扩展至 40–44px;两个交互元素的点击区域不得重叠;复选框/单选按钮及其标签共用一个连续的点击区域。
- 2.5.7 拖动操作——每项拖动操作都有点击/轻触替代方式。
- 3.3.7 冗余输入——同一工作流中不要重复询问相同信息。
- 3.3.8 无障碍身份验证——登录时不得要求完成认知测试;密码字段允许粘贴;提供通行密钥或电子邮件链接替代方式。
- 3.2.6 一致的帮助——每个页面上的帮助机制都出现在相同位置。
输出
对于每个问题:
**[Location: file or component/element]**
- **Issue:** [What is wrong.]
- **WCAG / principle:** [Criterion or principle, e.g. 1.3.1 Info and Relationships, 2.1.1 Keyboard.]
- **Impact:** [Who is affected and how.]
- **Recommendation:** [Concrete fix: code or attribute. For contrast findings, cite computed ratios: "#aaa on #fff = 2.32:1, needs 4.5:1 → use #595959 (7.0:1)".]
- **Severity:** Critical | High | Medium
已填写问题示例:
**[src/components/LoginForm.tsx — error message]**
- **Issue:** The "Invalid email" error renders visually below the field but is not associated with the input and is never announced.
- **WCAG / principle:** 3.3.1 Error Identification; 4.1.3 Status Messages.
- **Impact:** A screen-reader user submits, hears nothing, and cannot tell the form failed or which field to fix.
- **Recommendation:** Link it: `<input aria-describedby="email-err" aria-invalid="true">` + `<p id="email-err" role="alert">Invalid email</p>`; on submit, move focus to the first invalid field.
- **Severity:** Critical
总结:"已审核:[范围]。发现 X 个严重、Y 个高、Z 个中等问题。建议进行自动扫描(axe/Lighthouse)以及键盘/屏幕阅读器测试。"
严重性
- 严重——阻碍核心任务(例如,无法提交表单、无法使用键盘导航、必填字段没有标签)。发布前修复。
- 高——造成显著障碍(例如,对比度差、缺少标题、顺序令人困惑)。尽快修复。
- 中等——改进项(例如,冗余标签、轻微对比度问题)。列入待办,或在修改相关组件时修复。
好与坏的示例
按钮:
<div onclick="submit()">Submit</div>
<button type="submit">Submit</button>
图片:
<img src="decoration.svg" alt="" role="presentation">
<img src="chart.png" alt="Bar chart showing revenue up 20% in Q4">
表单:
<input type="email" placeholder="Email">
<label for="email">Email</label>
<input id="email" type="email" placeholder="[email protected]">
规则失效时
每个检查清单项都体现了一条默认规则,用于避免最常见的失效情形。当上下文让失效情形反转时,规则也可能需要反转——屏幕阅读器应跳过的装饰性元素需要设置 aria-hidden,而不是添加标签;原生 <button> 不应同时设置 keydown 处理程序(否则会重复触发)。关键在于识别何时需要反转,而不是死记硬背例外情况。例外情况绝不能突破正确性和无障碍访问的底线:键盘可操作性、程序化名称和足够的对比度都不容妥协。
规则
- 不要宣称完全合规——应表述为“在已审查范围内发现的问题”。建议进行自动化和人工测试,以实现全面覆盖。
- 优先使用原生 HTML——使用
<button>、<label>、<main>等。只有在无法用 HTML 表达语义时才使用 ARIA(例如,在自定义折叠面板上使用aria-expanded)。 - 组件库——如果项目使用组件库(例如 Radix、MUI),请说明该库的无障碍访问模式(焦点陷阱、角色),并确保正确使用,而不是重新实现。
检查清单(完成前)
- 明确定义范围
- 每项发现都包含位置、问题、WCAG 参考、建议和严重程度
- 至少涵盖语义结构、键盘操作和标签/名称
- 建议后续进行自动化和人工测试
- 未经完整审计,不得宣称“完全符合 WCAG 2.2”
反模式
| 反模式 | 更好的做法 |
|---|---|
| 只检查颜色对比度 | 涵盖键盘操作、标签、结构和动态内容 |
| 建议到处“添加 aria-label” | 优先使用可见标签和语义化 HTML;必要时再使用 ARIA |
| 忽略模态框中的焦点顺序 | 记录焦点陷阱和焦点返回行为 |
| 仅通过代码审查就宣称合规 | 建议使用 axe/Lighthouse,并使用真实辅助技术进行测试 |
评论
支持 Markdown