web-accessibility-audit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Accessibility 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

PrincipleDescription
PerceivableContent can be perceived through different senses
OperableInterface can be operated by all users
UnderstandableContent and interface are understandable
RobustContent works with assistive technologies
原则描述
Perceivable(可感知)内容可通过不同感官被用户感知
Operable(可操作)界面能够被所有用户操作
Understandable(可理解)内容和界面易于用户理解
Robust(健壮性)内容可与各类辅助技术协同工作

Conformance Levels

合规等级

LevelRequirementTarget
AMinimum accessibilityMust pass
AAStandard complianceShould pass (legal requirement in many jurisdictions)
AAAEnhanced accessibilityNice to have

等级要求目标
A基础可访问性必须达标
AA标准合规性建议达标(多数地区的法定要求)
AAA增强可访问性可选优化

12 Most Common WCAG Violations

12种最常见的WCAG违规问题

Based on WebAIM Million (2021) research analyzing top 1M websites:
  1. 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
  2. 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
  3. Missing Name, Role, or Value (WCAG 4.1.2)
    • Interactive elements without accessible names
    • Custom components without proper ARIA
    • Buttons, form fields, custom widgets
  4. Keyboard Navigation Failures (WCAG 2.1.1)
    • Elements with onClick but not keyboard accessible
    • Missing focus indicators
    • Trapped keyboard focus
  5. Unlabeled Form Controls (WCAG 1.3.1, 3.3.2) - 39.6% of sites
    • Inputs without
      <label>
      or aria-label
    • Labels not programmatically associated
  6. Missing Language Attributes (WCAG 3.1.1) - 28.9% of sites
    • No lang attribute on
      <html>
    • Missing lang for foreign language passages
  7. Improper Heading Structure (WCAG 1.3.1, 2.4.6)
    • Skipped heading levels (h1 → h3)
    • Multiple h1s or no h1
    • Empty headings
  8. Empty Links or Poor Link Text (WCAG 2.4.4)
    • Links with "click here", "here", "read more"
    • Empty links or links with only icons
  9. Missing/Improper Focus Indicators (WCAG 2.4.7)
    • CSS removing outline without replacement
    • Insufficient focus indicator contrast
  10. Overuse/Misuse of ARIA (WCAG 4.1.2)
    • Unnecessary ARIA when native HTML works
    • Invalid ARIA attributes for roles
    • Required ARIA attributes missing
  11. Inadequate Data Table Markup (WCAG 1.3.1)
    • Tables without
      <th>
      elements
    • Missing scope or headers attributes
  12. Missing Media Captions (WCAG 1.2.1, 1.2.2)
    • Videos without captions/subtitles
    • Audio without transcripts

基于WebAIM Million(2021)对Top 100万网站的分析:
  1. 颜色对比度不足(WCAG 1.4.3) - 86.4%的网站存在该问题
    • 普通文本对比度<4.5:1
    • 大文本对比度<3:1
    • UI组件对比度<3:1
  2. 缺少/不恰当的替代文本(WCAG 1.1.1) - 60.6%的网站存在该问题
    • 图片无alt属性
    • 替代文本仅包含“image”“picture”“photo”等词汇
    • 有意义的图片使用空alt属性
  3. 缺少名称、角色或值(WCAG 4.1.2)
    • 交互元素无可访问名称
    • 自定义组件未正确配置ARIA
    • 按钮、表单字段、自定义小部件存在该问题
  4. 键盘导航故障(WCAG 2.1.1)
    • 元素仅支持onClick但无法通过键盘访问
    • 缺少焦点指示器
    • 键盘焦点被陷阱锁定
  5. 未标记的表单控件(WCAG 1.3.1, 3.3.2) - 39.6%的网站存在该问题
    • 输入框无
      <label>
      或aria-label
    • 标签未与控件建立程序关联
  6. 缺少语言属性(WCAG 3.1.1) - 28.9%的网站存在该问题
    • <html>
      标签无lang属性
    • 外文段落缺少lang属性
  7. 不当的标题结构(WCAG 1.3.1, 2.4.6)
    • 跳过标题层级(如h1 → h3)
    • 多个h1或无h1标签
    • 空标题
  8. 空链接或链接文本描述性差(WCAG 2.4.4)
    • 链接文本为“click here”“here”“read more”等
    • 空链接或仅含图标的链接
  9. 缺少/不当的焦点指示器(WCAG 2.4.7)
    • CSS移除outline但未提供替代方案
    • 焦点指示器对比度不足
  10. ARIA过度使用/误用(WCAG 4.1.2)
    • 原生HTML可实现时仍使用不必要的ARIA
    • 角色使用无效的ARIA属性
    • 缺少必需的ARIA属性
  11. 数据表标记不当(WCAG 1.3.1)
    • 表格无
      <th>
      元素
    • 缺少scope或headers属性
  12. 缺少媒体字幕(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 || true
Or use helper script:
.claude/skills/a11y-auditor/scripts/run-eslint.sh
Run Lighthouse (production/staging):
bash
npx lighthouse https://example.com --only-categories=accessibility --output=json --output-path=./lighthouse-results.json
Check 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.json

Phase 2: Manual Code Inspection

第二阶段:手动代码检查

Use grep patterns from
references/grep-patterns.md
to search for:
  • 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
references/grep-patterns.md
for complete pattern list.
使用
references/grep-patterns.md
中的grep模式搜索以下问题:
  • 缺少替代文本
  • 键盘导航问题
  • 用于对比度检查的颜色值
  • ARIA相关问题
  • 表单标签
  • 标题结构
  • 语言属性
  • 描述性差的链接文本
  • 媒体元素
完整模式列表请查看
references/grep-patterns.md

Phase 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
references/screen-reader-guide.md
for:
  • 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
undefined

Accessibility 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
Locations:
  • path/to/file.tsx:123
  • path/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
位置:
  • path/to/file.tsx:123
  • path/to/file.tsx:456
问题描述: [简要说明]
修复方案:
tsx
// 修复前
<div onClick={handleClick}>点击我</div>

// 修复后
<button onClick={handleClick}>点击我</button>
原因: [可访问性原则]

Serious Issues

重要问题

[Same format]
[相同格式]

Moderate Issues

中等问题

[Same format]
[相同格式]

Testing Recommendations

测试建议

  1. Manual keyboard testing (Tab, Enter, Escape)
  2. Screen reader testing (see references/screen-reader-guide.md)
  3. Automated testing setup (@axe-core/react or Lighthouse CI)
  4. Color contrast validation (WebAIM Contrast Checker)
  1. 手动键盘测试(Tab、Enter、Escape键)
  2. 屏幕阅读器测试(参考references/screen-reader-guide.md)
  3. 自动化测试设置(@axe-core/react或Lighthouse CI)
  4. 颜色对比度验证(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

手动测试

Reference Docs

参考文档

  • references/WCAG-criteria.md
    - All WCAG 2.1 success criteria
  • references/ARIA-patterns.md
    - Common ARIA patterns and examples
  • references/screen-reader-guide.md
    - Testing commands and scenarios
  • references/grep-patterns.md
    - Search patterns for code audits
  • references/WCAG-criteria.md
    - 所有WCAG 2.1成功标准
  • references/ARIA-patterns.md
    - 常见ARIA模式及示例
  • references/screen-reader-guide.md
    - 测试命令与场景
  • references/grep-patterns.md
    - 代码审计搜索模式

References

外部参考



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

需避免的常见陷阱

  1. Relying solely on automated testing
  2. Using ARIA when native HTML suffices
  3. Removing focus indicators
  4. Using positive tabindex values
  5. Color as only means of conveying information
  6. Keyboard traps in modals/dialogs
  7. Non-descriptive link text
  8. Missing or incorrect heading hierarchy
  9. Unlabeled form controls
  10. Missing language attributes
  1. 仅依赖自动化测试
  2. 原生HTML可实现时仍使用ARIA
  3. 移除焦点指示器
  4. 使用正的tabindex值
  5. 仅通过颜色传达信息
  6. 模态框/对话框中的键盘焦点陷阱
  7. 非描述性链接文本
  8. 缺少或不正确的标题层级
  9. 未标记的表单控件
  10. 缺少语言属性