web-accessibility-audit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAccessibility Auditor
可访问性审计器
Audit web applications for WCAG 2.0/2.1/2.2 compliance by identifying common violations and providing actionable remediation steps.
通过识别常见违规问题并提供可执行的修复步骤,对Web应用进行WCAG 2.0/2.1/2.2合规性审计。
When to Use
适用场景
- User requests accessibility audit, a11y check, or WCAG compliance review
- User mentions accessibility issues, screen readers, or keyboard navigation problems
- User asks to check or improve accessibility for people with disabilities
- 用户请求进行可访问性审计、a11y检查或WCAG合规性评审
- 用户提及可访问性问题、屏幕阅读器或键盘导航故障
- 用户要求检查或提升面向残障人士的可访问性
WCAG Principles: POUR
WCAG原则:POUR
| Principle | Description |
|---|---|
| Perceivable | Content can be perceived through different senses |
| Operable | Interface can be operated by all users |
| Understandable | Content and interface are understandable |
| Robust | Content works with assistive technologies |
| 原则 | 描述 |
|---|---|
| Perceivable(可感知) | 内容可通过不同感官被用户感知 |
| Operable(可操作) | 界面能够被所有用户操作 |
| Understandable(可理解) | 内容和界面易于用户理解 |
| Robust(健壮性) | 内容可与各类辅助技术协同工作 |
Conformance Levels
合规等级
| Level | Requirement | Target |
|---|---|---|
| A | Minimum accessibility | Must pass |
| AA | Standard compliance | Should pass (legal requirement in many jurisdictions) |
| AAA | Enhanced accessibility | Nice to have |
| 等级 | 要求 | 目标 |
|---|---|---|
| A | 基础可访问性 | 必须达标 |
| AA | 标准合规性 | 建议达标(多数地区的法定要求) |
| AAA | 增强可访问性 | 可选优化 |
12 Most Common WCAG Violations
12种最常见的WCAG违规问题
Based on WebAIM Million (2021) research analyzing top 1M websites:
-
Low Color Contrast (WCAG 1.4.3) - 86.4% of sites
- Text < 4.5:1 contrast ratio
- Large text < 3:1 contrast ratio
- UI components < 3:1
-
Missing/Inadequate Alt Text (WCAG 1.1.1) - 60.6% of sites
- Images without alt attribute
- Alt text with "image", "picture", "photo"
- Empty alt on meaningful images
-
Missing Name, Role, or Value (WCAG 4.1.2)
- Interactive elements without accessible names
- Custom components without proper ARIA
- Buttons, form fields, custom widgets
-
Keyboard Navigation Failures (WCAG 2.1.1)
- Elements with onClick but not keyboard accessible
- Missing focus indicators
- Trapped keyboard focus
-
Unlabeled Form Controls (WCAG 1.3.1, 3.3.2) - 39.6% of sites
- Inputs without or aria-label
<label> - Labels not programmatically associated
- Inputs without
-
Missing Language Attributes (WCAG 3.1.1) - 28.9% of sites
- No lang attribute on
<html> - Missing lang for foreign language passages
- No lang attribute on
-
Improper Heading Structure (WCAG 1.3.1, 2.4.6)
- Skipped heading levels (h1 → h3)
- Multiple h1s or no h1
- Empty headings
-
Empty Links or Poor Link Text (WCAG 2.4.4)
- Links with "click here", "here", "read more"
- Empty links or links with only icons
-
Missing/Improper Focus Indicators (WCAG 2.4.7)
- CSS removing outline without replacement
- Insufficient focus indicator contrast
-
Overuse/Misuse of ARIA (WCAG 4.1.2)
- Unnecessary ARIA when native HTML works
- Invalid ARIA attributes for roles
- Required ARIA attributes missing
-
Inadequate Data Table Markup (WCAG 1.3.1)
- Tables without elements
<th> - Missing scope or headers attributes
- Tables without
-
Missing Media Captions (WCAG 1.2.1, 1.2.2)
- Videos without captions/subtitles
- Audio without transcripts
基于WebAIM Million(2021)对Top 100万网站的分析:
-
颜色对比度不足(WCAG 1.4.3) - 86.4%的网站存在该问题
- 普通文本对比度<4.5:1
- 大文本对比度<3:1
- UI组件对比度<3:1
-
缺少/不恰当的替代文本(WCAG 1.1.1) - 60.6%的网站存在该问题
- 图片无alt属性
- 替代文本仅包含“image”“picture”“photo”等词汇
- 有意义的图片使用空alt属性
-
缺少名称、角色或值(WCAG 4.1.2)
- 交互元素无可访问名称
- 自定义组件未正确配置ARIA
- 按钮、表单字段、自定义小部件存在该问题
-
键盘导航故障(WCAG 2.1.1)
- 元素仅支持onClick但无法通过键盘访问
- 缺少焦点指示器
- 键盘焦点被陷阱锁定
-
未标记的表单控件(WCAG 1.3.1, 3.3.2) - 39.6%的网站存在该问题
- 输入框无或aria-label
<label> - 标签未与控件建立程序关联
- 输入框无
-
缺少语言属性(WCAG 3.1.1) - 28.9%的网站存在该问题
- 标签无lang属性
<html> - 外文段落缺少lang属性
-
不当的标题结构(WCAG 1.3.1, 2.4.6)
- 跳过标题层级(如h1 → h3)
- 多个h1或无h1标签
- 空标题
-
空链接或链接文本描述性差(WCAG 2.4.4)
- 链接文本为“click here”“here”“read more”等
- 空链接或仅含图标的链接
-
缺少/不当的焦点指示器(WCAG 2.4.7)
- CSS移除outline但未提供替代方案
- 焦点指示器对比度不足
-
ARIA过度使用/误用(WCAG 4.1.2)
- 原生HTML可实现时仍使用不必要的ARIA
- 角色使用无效的ARIA属性
- 缺少必需的ARIA属性
-
数据表标记不当(WCAG 1.3.1)
- 表格无元素
<th> - 缺少scope或headers属性
- 表格无
-
缺少媒体字幕(WCAG 1.2.1, 1.2.2)
- 视频无字幕/副标题
- 音频无文字转录
Audit Process
审计流程
Phase 1: Automated Testing
第一阶段:自动化测试
Run ESLint (React/JSX projects):
bash
npx eslint --ext .jsx,.tsx --no-ignore --format json . > .claude/skills/a11y-auditor/eslint-results.json 2>&1 || trueOr use helper script:
.claude/skills/a11y-auditor/scripts/run-eslint.shRun Lighthouse (production/staging):
bash
npx lighthouse https://example.com --only-categories=accessibility --output=json --output-path=./lighthouse-results.jsonCheck for axe-core integration:
bash
grep -r "@axe-core\|axe-core" package.json运行ESLint(React/JSX项目):
bash
npx eslint --ext .jsx,.tsx --no-ignore --format json . > .claude/skills/a11y-auditor/eslint-results.json 2>&1 || true或使用辅助脚本:
.claude/skills/a11y-auditor/scripts/run-eslint.sh运行Lighthouse(生产/预发布环境):
bash
npx lighthouse https://example.com --only-categories=accessibility --output=json --output-path=./lighthouse-results.json检查axe-core集成情况:
bash
grep -r "@axe-core\|axe-core" package.jsonPhase 2: Manual Code Inspection
第二阶段:手动代码检查
Use grep patterns from to search for:
references/grep-patterns.md- Missing alt text
- Keyboard navigation issues
- Color values for contrast checking
- ARIA issues
- Form labels
- Heading structure
- Language attributes
- Poor link text
- Media elements
See for complete pattern list.
references/grep-patterns.md使用中的grep模式搜索以下问题:
references/grep-patterns.md- 缺少替代文本
- 键盘导航问题
- 用于对比度检查的颜色值
- ARIA相关问题
- 表单标签
- 标题结构
- 语言属性
- 描述性差的链接文本
- 媒体元素
完整模式列表请查看。
references/grep-patterns.mdPhase 3: Analyze & Prioritize
第三阶段:分析与优先级排序
Group findings by severity using WCAG impact levels:
Critical (fix immediately):
- Keyboard traps
- No focus indicators
- Missing form labels
- Missing alt text on functional images
- Insufficient color contrast on interactive elements
Serious (fix before launch):
- Missing page language
- Improper heading structure
- Non-descriptive link text
- Missing skip links
- Auto-playing media
Moderate (fix soon):
- Missing ARIA labels on icons
- Inconsistent navigation
- Missing error identification
- Missing landmark regions
根据WCAG影响级别按严重程度分组发现的问题:
严重(立即修复):
- 键盘焦点陷阱
- 无焦点指示器
- 缺少表单标签
- 功能性图片缺少替代文本
- 交互元素颜色对比度不足
重要(上线前修复):
- 缺少页面语言属性
- 不当的标题结构
- 非描述性链接文本
- 缺少跳转链接
- 自动播放媒体
中等(尽快修复):
- 图标缺少ARIA标签
- 导航不一致
- 缺少错误标识
- 缺少地标区域
Phase 4: Manual Testing
第四阶段:手动测试
Follow for:
references/screen-reader-guide.md- Keyboard navigation testing
- Screen reader testing (VoiceOver, NVDA, JAWS)
- Zoom and reflow testing
- High contrast mode testing
- Reduced motion testing
遵循执行以下测试:
references/screen-reader-guide.md- 键盘导航测试
- 屏幕阅读器测试(VoiceOver、NVDA、JAWS)
- 缩放与重排测试
- 高对比度模式测试
- 减少动画测试
WCAG Pattern Examples
WCAG模式示例
Perceivable
可感知
Alt Text (1.1.1)
替代文本(1.1.1)
html
<!-- ❌ Missing alt -->
<img src="chart.png">
<!-- ✅ Descriptive alt -->
<img src="chart.png" alt="Bar chart showing 40% increase in Q3 sales">
<!-- ✅ Decorative (empty alt) -->
<img src="decorative-border.png" alt="" role="presentation">html
<!-- ❌ 缺少替代文本 -->
<img src="chart.png">
<!-- ✅ 描述性替代文本 -->
<img src="chart.png" alt="显示第三季度销售额增长40%的柱状图">
<!-- ✅ 装饰性图片(空替代文本) -->
<img src="decorative-border.png" alt="" role="presentation">Color Contrast (1.4.3)
颜色对比度(1.4.3)
css
/* ❌ Low contrast (2.5:1) */
.low-contrast {
color: #999;
background: #fff;
}
/* ✅ Sufficient contrast (7:1) */
.high-contrast {
color: #333;
background: #fff;
}Contrast requirements:
- Normal text: 4.5:1 (AA), 7:1 (AAA)
- Large text (18px+ or 14px+ bold): 3:1 (AA), 4.5:1 (AAA)
- UI components: 3:1
css
/* ❌ 低对比度(2.5:1) */
.low-contrast {
color: #999;
background: #fff;
}
/* ✅ 足够对比度(7:1) */
.high-contrast {
color: #333;
background: #fff;
}对比度要求:
- 普通文本:4.5:1(AA级),7:1(AAA级)
- 大文本(18px+或14px+粗体):3:1(AA级),4.5:1(AAA级)
- UI组件:3:1
Media Alternatives (1.2)
媒体替代方案(1.2)
html
<video controls>
<source src="video.mp4" type="video/mp4">
<track kind="captions" src="captions.vtt" srclang="en" label="English" default>
</video>html
<video controls>
<source src="video.mp4" type="video/mp4">
<track kind="captions" src="captions.vtt" srclang="en" label="English" default>
</video>Operable
可操作
Keyboard Navigation (2.1.1)
键盘导航(2.1.1)
javascript
// ❌ Only click
element.addEventListener('click', handleAction);
// ✅ Click + keyboard
element.addEventListener('click', handleAction);
element.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleAction();
}
});javascript
// ❌ 仅支持点击
element.addEventListener('click', handleAction);
// ✅ 支持点击+键盘操作
element.addEventListener('click', handleAction);
element.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleAction();
}
});Focus Visible (2.4.7)
焦点可见(2.4.7)
css
/* ❌ Never remove focus */
*:focus { outline: none; }
/* ✅ Keyboard-only focus */
:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}css
/* ❌ 切勿移除焦点样式 */
*:focus { outline: none; }
/* ✅ 仅键盘操作时显示焦点 */
:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}Skip Links (2.4.1)
跳转链接(2.4.1)
html
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header><!-- navigation --></header>
<main id="main-content" tabindex="-1">
<!-- content -->
</main>
</body>css
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px 16px;
z-index: 100;
}
.skip-link:focus {
top: 0;
}html
<body>
<a href="#main-content" class="skip-link">跳转到主内容</a>
<header><!-- 导航 --></header>
<main id="main-content" tabindex="-1">
<!-- 内容 -->
</main>
</body>css
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px 16px;
z-index: 100;
}
.skip-link:focus {
top: 0;
}Reduced Motion (2.3.3)
减少动画(2.3.3)
css
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}css
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}Understandable
可理解
Page Language (3.1.1)
页面语言(3.1.1)
html
<!-- ❌ No language -->
<html>
<!-- ✅ Language specified -->
<html lang="en">
<!-- ✅ Language changes -->
<p>The French word for hello is <span lang="fr">bonjour</span>.</p>html
<!-- ❌ 无语言属性 -->
<html>
<!-- ✅ 指定语言 -->
<html lang="en">
<!-- ✅ 语言切换 -->
<p>法语中“你好”的说法是<span lang="fr">bonjour</span>。</p>Form Labels (3.3.2)
表单标签(3.3.2)
html
<!-- ❌ No label -->
<input type="email" placeholder="Email">
<!-- ✅ Explicit label -->
<label for="email">Email address</label>
<input type="email" id="email" autocomplete="email">
<!-- ✅ With hint -->
<label for="password">Password</label>
<input type="password" id="password" aria-describedby="password-requirements">
<p id="password-requirements">
Must be at least 8 characters with one number.
</p>html
<!-- ❌ 无标签 -->
<input type="email" placeholder="Email">
<!-- ✅ 显式标签 -->
<label for="email">电子邮箱</label>
<input type="email" id="email" autocomplete="email">
<!-- ✅ 带提示信息 -->
<label for="password">密码</label>
<input type="password" id="password" aria-describedby="password-requirements">
<p id="password-requirements">
长度至少8位,且包含一个数字。
</p>Error Handling (3.3.1)
错误处理(3.3.1)
html
<label for="email">Email</label>
<input type="email" id="email"
aria-invalid="true"
aria-describedby="email-error">
<p id="email-error" role="alert">
Please enter a valid email address.
</p>html
<label for="email">电子邮箱</label>
<input type="email" id="email"
aria-invalid="true"
aria-describedby="email-error">
<p id="email-error" role="alert">
请输入有效的电子邮箱地址。
</p>Robust
健壮性
ARIA Usage (4.1.2)
ARIA使用(4.1.2)
html
<!-- ❌ Unnecessary ARIA -->
<button role="button">Submit</button>
<!-- ✅ Native HTML -->
<button>Submit</button>
<!-- ✅ ARIA when needed (custom tabs) -->
<div role="tablist" aria-label="Product information">
<button role="tab" aria-selected="true" aria-controls="panel-1">
Description
</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" tabindex="-1">
Reviews
</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
<!-- content -->
</div>html
<!-- ❌ 不必要的ARIA -->
<button role="button">提交</button>
<!-- ✅ 原生HTML实现 -->
<button>提交</button>
<!-- ✅ 必要时使用ARIA(自定义标签页) -->
<div role="tablist" aria-label="产品信息">
<button role="tab" aria-selected="true" aria-controls="panel-1">
产品描述
</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" tabindex="-1">
用户评价
</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
<!-- 内容 -->
</div>Live Regions (4.1.3)
实时区域(4.1.3)
html
<!-- Polite (waits for pause) -->
<div aria-live="polite" aria-atomic="true">
Status update
</div>
<!-- Assertive (interrupts) -->
<div role="alert" aria-live="assertive">
Error: Form submission failed
</div>html
<!-- 礼貌模式(等待停顿后更新) -->
<div aria-live="polite" aria-atomic="true">
状态更新
</div>
<!-- 主动模式(立即打断) -->
<div role="alert" aria-live="assertive">
错误:表单提交失败
</div>Visually Hidden Text
视觉隐藏文本
css
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}html
<button>
<svg aria-hidden="true"><!-- icon --></svg>
<span class="visually-hidden">Delete item</span>
</button>css
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}html
<button>
<svg aria-hidden="true"><!-- 图标 --></svg>
<span class="visually-hidden">删除项目</span>
</button>Output Format
输出格式
Generate reports structured as:
markdown
undefined生成如下结构的报告:
markdown
undefinedAccessibility Audit Report
可访问性审计报告
Summary
摘要
- Total Issues: X
- Critical: X | Serious: X | Moderate: X | Minor: X
- WCAG Level: A, AA, or AAA
- Automated Coverage: ~57% (manual testing required)
- 问题总数:X
- 严重:X | 重要:X | 中等:X | 轻微:X
- WCAG等级:A、AA或AAA
- 自动化覆盖率:约57%(需手动测试)
Critical Issues (Fix Immediately)
严重问题(立即修复)
1. [Issue Name] - WCAG X.X.X
1. [问题名称] - WCAG X.X.X
Severity: Critical
Impact: [Who is affected and how]
Affected: X elements
Impact: [Who is affected and how]
Affected: X elements
Locations:
path/to/file.tsx:123path/to/file.tsx:456
Problem:
[Brief description]
Fix:
tsx
// Before
<div onClick={handleClick}>Click me</div>
// After
<button onClick={handleClick}>Click me</button>Why: [Accessibility principle]
严重程度: 严重
影响: [受影响人群及影响方式]
受影响元素数量: X
影响: [受影响人群及影响方式]
受影响元素数量: X
位置:
path/to/file.tsx:123path/to/file.tsx:456
问题描述:
[简要说明]
修复方案:
tsx
// 修复前
<div onClick={handleClick}>点击我</div>
// 修复后
<button onClick={handleClick}>点击我</button>原因: [可访问性原则]
Serious Issues
重要问题
[Same format]
[相同格式]
Moderate Issues
中等问题
[Same format]
[相同格式]
Testing Recommendations
测试建议
- Manual keyboard testing (Tab, Enter, Escape)
- Screen reader testing (see references/screen-reader-guide.md)
- Automated testing setup (@axe-core/react or Lighthouse CI)
- Color contrast validation (WebAIM Contrast Checker)
- 手动键盘测试(Tab、Enter、Escape键)
- 屏幕阅读器测试(参考references/screen-reader-guide.md)
- 自动化测试设置(@axe-core/react或Lighthouse CI)
- 颜色对比度验证(WebAIM Contrast Checker)
Next Steps
后续步骤
[Prioritized action items]
---[按优先级排序的行动项]
---Tools & Resources
工具与资源
Development Tools
开发工具
- eslint-plugin-jsx-a11y - React/JSX static analysis (~37 rules)
- axe-core DevTools - Browser extension for runtime testing
- Lighthouse - Built into Chrome DevTools
- eslint-plugin-jsx-a11y - React/JSX静态分析工具(约37条规则)
- axe-core DevTools - 用于运行时测试的浏览器扩展
- Lighthouse - Chrome DevTools内置工具
Testing Tools
测试工具
- @axe-core/react - Runtime accessibility testing
- @axe-core/playwright - E2E test integration
- pa11y - Automated command-line testing
- @axe-core/react - 运行时可访问性测试工具
- @axe-core/playwright - 端到端测试集成工具
- pa11y - 自动化命令行测试工具
Manual Testing
手动测试
- WebAIM Contrast Checker - https://webaim.org/resources/contrastchecker/
- WAVE - Browser extension for visual feedback
- Screen readers - NVDA (Windows), VoiceOver (macOS), JAWS
- WebAIM Contrast Checker - https://webaim.org/resources/contrastchecker/
- WAVE - 提供视觉反馈的浏览器扩展
- 屏幕阅读器 - NVDA(Windows)、VoiceOver(macOS)、JAWS
Reference Docs
参考文档
- - All WCAG 2.1 success criteria
references/WCAG-criteria.md - - Common ARIA patterns and examples
references/ARIA-patterns.md - - Testing commands and scenarios
references/screen-reader-guide.md - - Search patterns for code audits
references/grep-patterns.md
- - 所有WCAG 2.1成功标准
references/WCAG-criteria.md - - 常见ARIA模式及示例
references/ARIA-patterns.md - - 测试命令与场景
references/screen-reader-guide.md - - 代码审计搜索模式
references/grep-patterns.md
References
外部参考
- WebAIM Million - Annual analysis of top 1M websites (violation statistics)
- WCAG 2.1 Quick Reference - Interactive WCAG guide
- WAI-ARIA Authoring Practices - Official ARIA patterns
- Deque axe Rules - All axe-core rules explained
- jsx-a11y Rules - ESLint accessibility rules
- WebAIM Million - 年度Top 100万网站分析(违规统计)
- WCAG 2.1 Quick Reference - 交互式WCAG指南
- WAI-ARIA Authoring Practices - 官方ARIA模式
- Deque axe Rules - axe-core所有规则详解
- jsx-a11y Rules - ESLint可访问性规则
Important Notes
重要说明
- Automated tools catch 30-57% of issues; manual testing required
- Pages with ARIA average 41% more errors than without
- Always test with actual assistive technology when possible
- Focus on critical issues first (keyboard, screen readers, contrast)
- Document deliberate accessibility decisions
- Test on multiple browsers and devices
- Include users with disabilities in testing when possible
- 自动化工具可检测30-57%的问题,仍需手动测试
- 使用ARIA的页面平均比不使用的页面多41%的错误
- 尽可能使用实际辅助技术进行测试
- 优先修复严重问题(键盘、屏幕阅读器、对比度相关)
- 记录刻意做出的可访问性决策
- 在多个浏览器和设备上进行测试
- 尽可能让残障用户参与测试
Common Pitfalls to Avoid
需避免的常见陷阱
- Relying solely on automated testing
- Using ARIA when native HTML suffices
- Removing focus indicators
- Using positive tabindex values
- Color as only means of conveying information
- Keyboard traps in modals/dialogs
- Non-descriptive link text
- Missing or incorrect heading hierarchy
- Unlabeled form controls
- Missing language attributes
- 仅依赖自动化测试
- 原生HTML可实现时仍使用ARIA
- 移除焦点指示器
- 使用正的tabindex值
- 仅通过颜色传达信息
- 模态框/对话框中的键盘焦点陷阱
- 非描述性链接文本
- 缺少或不正确的标题层级
- 未标记的表单控件
- 缺少语言属性