网页无障碍审计专家Skill AccessibilityAuditor

这个技能用于网页可访问性审计,确保网站符合WCAG 2.1 AA/AAA标准,实现ARIA属性,测试屏幕阅读器兼容性,并提供无障碍设计指导。关键词:网页可访问性、WCAG合规、ARIA实现、无障碍设计、屏幕阅读器测试、ADA合规。

前端开发 0 次安装 0 次浏览 更新于 3/21/2026

name: 可访问性审计专家 description: 网页可访问性专家,专注于WCAG合规、ARIA实现和包容性设计。在审计网站可访问性问题、实施WCAG 2.1 AA/AAA标准、使用屏幕阅读器测试或确保ADA合规时使用。精通语义HTML、键盘导航和辅助技术兼容性。

可访问性审计专家

创建符合WCAG标准并有效服务所有能力用户的网页体验的全面指南。

何时使用此技能

在以下情况使用此技能:

  • 审计网站的可访问性合规性
  • 实施WCAG 2.1 Level AA或AAA标准
  • 修复可访问性违规和错误
  • 使用屏幕阅读器测试(NVDA、JAWS、VoiceOver)
  • 确保键盘导航正常工作
  • 实现ARIA属性和地标
  • 准备ADA或Section 508合规审计
  • 设计包容性用户体验

WCAG 2.1原则(POUR)

1. 可感知

用户必须能够感知所呈现的信息。

2. 可操作

用户必须能够操作界面。

3. 可理解

用户必须能够理解信息和界面。

4. 健壮

内容必须足够健壮,以与当前和未来技术兼容。

常见可访问性问题与修复

1. 图像缺少替代文本

❌ 问题:

<img src="/products/shoes.jpg">

✅ 解决方案:

<!-- 信息性图像 -->
<img src="/products/shoes.jpg" alt="红色Nike Air Max跑鞋,带有白色勾号">

<!-- 装饰性图像 -->
<img src="/decorative-pattern.svg" alt="" role="presentation">

<!-- 链接的徽标 -->
<a href="/">
  <img src="/logo.png" alt="公司名称 - 首页">
</a>

规则:

  • 信息性图像:描述内容/功能
  • 装饰性图像:使用空alt(alt=“”)
  • 功能性图像:描述操作
  • 复杂图像:在附近提供详细描述

2. 低颜色对比度

❌ 问题:

/* 对比度比例2.5:1 - 不符合WCAG */
.text {
  color: #767676;
  background: #ffffff;
}

✅ 解决方案:

/* 对比度比例4.5:1+ - 符合AA级 */
.text {
  color: #595959;
  background: #ffffff;
}

/* 对比度比例7:1+ - 符合AAA级 */
.text-high-contrast {
  color: #333333;
  background: #ffffff;
}

要求:

  • 正常文本(< 18px):最低4.5:1(AA级),增强7:1(AAA级)
  • 大文本(≥ 18px或≥ 14px加粗):最低3:1(AA级),增强4.5:1(AAA级)
  • UI组件和图形:最低3:1

3. 非语义HTML

❌ 问题:

<div class="button" onclick="submitForm()">提交</div>
<div class="heading">页面标题</div>
<div class="nav-menu">...</div>

✅ 解决方案:

<button type="submit" onclick="submitForm()">提交</button>
<h1>页面标题</h1>
<nav aria-label="主导航">...</nav>

语义元素:

  • <button> 用于按钮
  • <a> 用于链接
  • <h1> - <h6> 用于标题(层级)
  • <nav>, <main>, <aside>, <article>, <section> 用于地标
  • <ul>, <ol>, <li> 用于列表
  • <table>, <th>, <td> 用于表格数据

4. 缺少表单标签

❌ 问题:

<input type="email" placeholder="输入您的邮箱">

✅ 解决方案:

<!-- 显式标签 -->
<label for="email">邮箱地址</label>
<input type="email" id="email" name="email">

<!-- 隐式标签 -->
<label>
  邮箱地址
  <input type="email" name="email">
</label>

<!-- 隐藏标签(适用于紧凑布局) -->
<label for="search" class="sr-only">搜索</label>
<input type="text" id="search" placeholder="搜索...">

最佳实践:

  • 每个表单字段必须有相关标签
  • 标签应可见(不要依赖占位符)
  • 仅当视觉标签不可行时使用aria-label
  • 使用<fieldset><legend>分组相关字段

5. 键盘导航问题

❌ 问题:

<div onclick="handleClick()">点击我</div>
<a href="javascript:void(0)" onclick="doSomething()">操作</a>

✅ 解决方案:

<!-- 使用适当按钮 -->
<button onclick="handleClick()">点击我</button>

<!-- 如果必须使用div,使其可访问 -->
<div
  role="button"
  tabindex="0"
  onclick="handleClick()"
  onkeydown="handleKeyPress(event)"
>
  点击我
</div>

<script>
function handleKeyPress(event) {
  if (event.key === 'Enter' || event.key === ' ') {
    event.preventDefault();
    handleClick();
  }
}
</script>

键盘要求:

  • 所有交互元素必须键盘可访问
  • 可见焦点指示器(轮廓或自定义样式)
  • 逻辑Tab顺序(匹配视觉流)
  • 跳过链接用于重复内容
  • 无键盘陷阱(用户可导航离开)

6. 缺少ARIA地标

❌ 问题:

<div class="header">...</div>
<div class="main-content">...</div>
<div class="sidebar">...</div>
<div class="footer">...</div>

✅ 解决方案:

<header role="banner">
  <nav aria-label="主导航">...</nav>
</header>

<main role="main">
  <h1>页面标题</h1>
  <article>...</article>
</main>

<aside role="complementary" aria-label="相关文章">
  ...
</aside>

<footer role="contentinfo">
  ...
</footer>

常见地标:

  • banner - 网站头部
  • navigation - 导航菜单
  • main - 主要内容(每页一个)
  • complementary - 辅助内容
  • contentinfo - 网站页脚
  • search - 搜索功能
  • form - 表单区域

7. 不可访问的模态框/对话框

❌ 问题:

<div class="modal">
  <div class="content">
    模态框内容
    <button onclick="closeModal()">关闭</button>
  </div>
</div>

✅ 解决方案:

<div
  role="dialog"
  aria-modal="true"
  aria-labelledby="modal-title"
  aria-describedby="modal-desc"
>
  <h2 id="modal-title">确认操作</h2>
  <p id="modal-desc">您确定要删除此项吗?</p>

  <button onclick="confirmAction()">确认</button>
  <button onclick="closeModal()">取消</button>
</div>

<script>
// 焦点管理
function openModal() {
  const modal = document.querySelector('[role="dialog"]');
  const focusableElements = modal.querySelectorAll(
    'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
  );

  // 存储先前焦点
  previousFocus = document.activeElement;

  // 聚焦第一个元素
  focusableElements[0].focus();

  // 陷阱焦点
  modal.addEventListener('keydown', trapFocus);
}

function closeModal() {
  // 恢复焦点
  if (previousFocus) previousFocus.focus();
}

function trapFocus(event) {
  if (event.key !== 'Tab') return;

  const focusableElements = Array.from(
    modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')
  );

  const firstElement = focusableElements[0];
  const lastElement = focusableElements[focusableElements.length - 1];

  if (event.shiftKey && document.activeElement === firstElement) {
    lastElement.focus();
    event.preventDefault();
  } else if (!event.shiftKey && document.activeElement === lastElement) {
    firstElement.focus();
    event.preventDefault();
  }
}
</script>

模态框要求:

  • role="dialog"role="alertdialog"
  • aria-modal="true" 表示模态行为
  • aria-labelledby 指向标题
  • aria-describedby 用于描述(可选)
  • 焦点管理(陷阱和恢复)
  • 按Escape键关闭
  • 防止背景滚动

8. 缺少跳过链接

✅ 解决方案:

<a href="#main-content" class="skip-link">
  跳转到主要内容
</a>

<header>
  <nav>...</nav>
</header>

<main id="main-content" tabindex="-1">
  <!-- 页面内容 -->
</main>

<style>
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px;
  text-decoration: none;
  z-index: 100;
}

.skip-link:focus {
  top: 0;
}
</style>

ARIA最佳实践

ARIA属性参考

状态:

  • aria-checked - 复选框/单选按钮状态
  • aria-disabled - 禁用状态
  • aria-expanded - 展开/折叠状态
  • aria-hidden - 对辅助技术隐藏
  • aria-pressed - 切换按钮状态
  • aria-selected - 选中状态

属性:

  • aria-label - 可访问名称
  • aria-labelledby - 标签的ID引用
  • aria-describedby - 描述的ID引用
  • aria-live - 实时区域更新
  • aria-required - 必填字段
  • aria-invalid - 验证状态

实时区域

<!-- 礼貌:等待语音暂停 -->
<div aria-live="polite" aria-atomic="true">
  已添加到购物车
</div>

<!-- 断言:立即中断 -->
<div aria-live="assertive" role="alert">
  错误:支付失败
</div>

<!-- 状态消息 -->
<div role="status" aria-live="polite">
  正在保存更改...
</div>

自定义组件

手风琴:

<div class="accordion">
  <button
    aria-expanded="false"
    aria-controls="panel-1"
    id="accordion-1"
  >
    第1节
  </button>
  <div id="panel-1" role="region" aria-labelledby="accordion-1" hidden>
    面板内容
  </div>
</div>

标签页:

<div role="tablist" aria-label="内容部分">
  <button
    role="tab"
    aria-selected="true"
    aria-controls="panel-1"
    id="tab-1"
  >
    标签页1
  </button>
  <button
    role="tab"
    aria-selected="false"
    aria-controls="panel-2"
    id="tab-2"
    tabindex="-1"
  >
    标签页2
  </button>
</div>

<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
  面板1内容
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
  面板2内容
</div>

测试清单

自动化测试

  • [ ] 运行axe DevTools或WAVE浏览器扩展
  • [ ] 检查HTML验证(W3C验证器)
  • [ ] 测试颜色对比度比例
  • [ ] 验证标题层次
  • [ ] 检查缺少替代文本

手动测试

  • [ ] 仅使用键盘导航整个网站(Tab、Enter、Escape、方向键)
  • [ ] 使用屏幕阅读器测试(NVDA、JAWS或VoiceOver)
  • [ ] 验证焦点指示器是否可见
  • [ ] 检查表单验证消息是否被宣布
  • [ ] 测试模态框焦点陷阱
  • [ ] 验证跳过链接是否工作
  • [ ] 测试浏览器缩放至200%
  • [ ] 检查不同视口大小下的页面重排
  • [ ] 禁用JavaScript并验证核心功能
  • [ ] 测试Windows高对比度模式

屏幕阅读器测试

VoiceOver(Mac):

  • 启用:Cmd + F5
  • 导航:Control + Option + 方向键
  • 阅读全部:Control + Option + A

NVDA(Windows):

  • 导航:方向键(浏览模式)或Tab(焦点模式)
  • 阅读全部:NVDA + 向下键
  • 元素列表:NVDA + F7

测试场景:

  • 用户能理解页面结构吗?
  • 标题是否描述性且层次化?
  • 表单标签是否清晰且相关?
  • 错误消息是否被宣布?
  • 用户能否在没有视觉的情况下完成关键任务?

可访问性声明

在网站上包含:

# 可访问性声明

我们致力于确保数字可访问性,为残障人士提供支持。我们持续改进用户体验并应用相关可访问性标准。

## 合规状态
本网站部分符合WCAG 2.1 Level AA。“部分符合”意味着某些内容未完全符合可访问性标准。

## 反馈
我们欢迎您对本网站可访问性的反馈。请通过以下方式联系我们:
- 邮箱:accessibility@example.com
- 电话:+1-555-0123

## 已知问题
- [列出任何已知可访问性问题及计划修复]

最后更新:[日期]

资源

工具:

  • axe DevTools(浏览器扩展)
  • WAVE(网页可访问性评估工具)
  • Lighthouse(Chrome DevTools)
  • 颜色对比度分析器
  • 屏幕阅读器:NVDA、JAWS、VoiceOver

指南:

可访问性不是可选的——它是创建包容性网页体验的基本要求。从每个项目开始就优先考虑,而不是事后补丁。