无
无障碍设计(WCAG 2.1 AA)
作者:鹿Sir开发工具v1
WCAG 2.1 AA 合规模式、屏幕阅读器兼容、键盘导航与 ARIA 最佳实践指南。覆盖语义化 HTML、焦点管理、颜色对比度与辅助技术测试。当用户需要实现可访问界面、审查 UI 组件无障碍性、开展 WCAG 合规审计、设计键盘导航或为自定义组件编写 ARIA 时触发。触发词:无障碍、可访问性、WCAG、ARIA、屏幕阅读器、键盘导航、对比度、a11y。
下载量
356
点赞
87
价格
免费
技能文档
---
name: diegosouzapw-accessibility-design
title: 无障碍设计(WCAG 2.1 AA)
category: 开发工具
description: "WCAG 2.1 AA 合规模式、屏幕阅读器兼容、键盘导航与 ARIA 最佳实践指南。覆盖语义化 HTML、焦点管理、颜色对比度与辅助技术测试。当用户需要实现可访问界面、审查 UI 组件无障碍性、开展 WCAG 合规审计、设计键盘导航或为自定义组件编写 ARIA 时触发。触发词:无障碍、可访问性、WCAG、ARIA、屏幕阅读器、键盘导航、对比度、a11y。"
---
# 无障碍设计(Accessibility Design)
以无障碍专家的角色,为数字产品提供 WCAG 2.1 AA 合规的全面实施指导,建立语义化标记、辅助技术兼容与包容性交互设计的模式。
## 技能工作流
### 步骤1:确认适用场景与硬性约束
适用场景:实现可访问用户界面、审查 UI 组件无障碍合规性、审计 WCAG 2.1 AA 合规、设计键盘导航模式、为自定义组件实现 ARIA、使用屏幕阅读器与辅助技术测试、确保颜色对比度与视觉无障碍。
六条硬性约束(任何场景不可违反):
1. **语义化 HTML 优先** — ARIA 只用于增强,绝不能替代正确的标记
2. 优先使用原生 HTML 元素
3. 绝不完全移除焦点指示器
4. 绝不仅靠颜色传达信息
5. 所有功能必须可通过键盘访问
6. 保持逻辑的标题层级顺序,不跳级
### 步骤2:按 POUR 四原则评估
所有无障碍工作遵循 POUR 四原则:
- **可感知(Perceivable)**:为非文本内容提供文本替代;内容可适配不同呈现方式;内容可辨别(颜色、对比度、音频控制)
- **可操作(Operable)**:所有功能键盘可访问;提供足够时间阅读和使用内容;避免引发癫痫或身体反应的内容;帮助用户导航、查找内容并确定位置
- **可理解(Understandable)**:文本可读可理解;页面呈现与操作可预测;帮助用户避免和纠正错误
- **健壮(Robust)**:最大化兼容当前与未来的辅助技术;使用有效、语义化的标记;确保所有功能可被程序化访问
### 步骤3:语义化 HTML 与渐进增强
正确示范:
```html
<button type="submit">Submit Form</button>
```
错误示范:
```html
<div role="button" tabindex="0" onclick="submit()">Submit Form</div>
```
原生元素选用:
- `<button>` 用于动作,`<a href>` 用于导航
- `<input>`、`<select>`、`<textarea>` 用于表单控件
- `<nav>`、`<main>`、`<aside>`、`<header>`、`<footer>` 作为地标区域
- `<h1>` 到 `<h6>` 构成标题层级
文档结构与跳转链接:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Descriptive Page Title - Site Name</title>
</head>
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header role="banner">
<nav aria-label="Main navigation">
<!-- Navigation content -->
</nav>
</header>
<main id="main-content" role="main">
<h1>Page Heading</h1>
<!-- Page content -->
</main>
<footer role="contentinfo">
<!-- Footer content -->
</footer>
</body>
</html>
```
跳转链接样式:
```css
.skip-link {
position: absolute;
top: -40px;
left: 0;
padding: 8px 16px;
background: #000;
color: #fff;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
```
渐进增强四层:语义化 HTML 提供无障碍基线 → CSS 增强呈现而不破坏结构 → JavaScript 增加交互同时保持键盘访问 → ARIA 补足 HTML 未覆盖的复杂组件。
### 步骤4:焦点管理与键盘导航
可见焦点指示器:
```css
:focus {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
/* Enhanced focus for better visibility */
:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 3px;
box-shadow: 0 0 0 6px rgba(0, 95, 204, 0.25);
}
/* Never remove focus indicators entirely */
:focus:not(:focus-visible) {
outline: 2px solid transparent;
box-shadow: 0 0 0 2px #005fcc;
}
```
模态框焦点圈定:
```javascript
function trapFocus(element) {
const focusableElements = element.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstFocusable = focusableElements[0];
const lastFocusable = focusableElements[focusableElements.length - 1];
element.addEventListener('keydown', (e) => {
if (e.key !== 'Tab') return;
if (e.shiftKey) {
if (document.activeElement === firstFocusable) {
lastFocusable.focus();
e.preventDefault();
}
} else {
if (document.activeElement === lastFocusable) {
firstFocusable.focus();
e.preventDefault();
}
}
});
}
```
标准键盘操作约定:
| 按键 | 动作 |
|------|------|
| Tab | 焦点移到下一个可聚焦元素 |
| Shift+Tab | 焦点移到上一个可聚焦元素 |
| Enter/Space | 激活按钮和链接 |
| 方向键 | 在组件内导航(菜单、选项卡、单选组) |
| Escape | 关闭模态框、菜单、下拉框 |
| Home/End | 移到列表第一项/最后一项 |
Tab 顺序规则:Tab 顺序必须与视觉顺序一致;**禁止使用正数 `tabindex`**;`tabindex="0"` 让非交互元素可聚焦;`tabindex="-1"` 让元素可被程序聚焦但不进 Tab 序列。
```html
<!-- Correct: Tab order matches visual order -->
<form>
<label for="name">Name</label>
<input id="name" type="text">
<label for="email">Email</label>
<input id="email" type="email">
<button type="submit">Submit</button>
</form>
```
### 步骤5:ARIA 模式
ARIA 使用时机:自定义组件(Tabs、手风琴、轮播、树形视图);动态内容(实时区域播报更新);关系连接(标签关联复杂控件);状态表达(展开/折叠、选中、按下)。
选项卡模式:
```html
<!-- Tab pattern -->
<div role="tablist" aria-label="Settings tabs">
<button role="tab" aria-selected="true" aria-controls="panel1" id="tab1">
General
</button>
<button role="tab" aria-selected="false" aria-controls="panel2" id="tab2">
Security
</button>
</div>
<div role="tabpanel" id="panel1" aria-labelledby="tab1">
<!-- Panel content -->
</div>
<div role="tabpanel" id="panel2" aria-labelledby="tab2" hidden>
<!-- Panel content -->
</div>
```
常用 ARIA 状态与属性:
| 属性 | 用途 | 示例 |
|------|------|------|
| `aria-expanded` | 表示可展开元素状态 | `aria-expanded="false"` |
| `aria-selected` | 表示选中状态 | `aria-selected="true"` |
| `aria-pressed` | 表示切换按钮状态 | `aria-pressed="mixed"` |
| `aria-hidden` | 对辅助技术隐藏内容 | `aria-hidden="true"` |
| `aria-live` | 播报动态内容 | `aria-live="polite"` |
| `aria-describedby` | 引用描述性内容 | `aria-describedby="hint"` |
| `aria-labelledby` | 引用标注性内容 | `aria-labelledby="heading"` |
实时区域:
```html
<!-- Polite: Announces when user is idle -->
<div aria-live="polite" aria-atomic="true">
Form saved successfully
</div>
<!-- Assertive: Interrupts immediately (use sparingly) -->
<div aria-live="assertive" role="alert">
Error: Please correct the highlighted fields
</div>
<!-- Status messages -->
<div role="status">
Loading... 50% complete
</div>
```
### 步骤6:表单无障碍
标签与说明:
```html
<!-- Explicit label association -->
<label for="username">Username</label>
<input type="text" id="username" name="username"
aria-describedby="username-hint">
<span id="username-hint">Must be 3-20 characters</span>
<!-- Grouped controls with fieldset -->
<fieldset>
<legend>Shipping Address</legend>
<label for="street">Street</label>
<input type="text" id="street">
<!-- More fields -->
</fieldset>
```
错误处理:
```html
<label for="email">Email</label>
<input type="email" id="email"
aria-invalid="true"
aria-describedby="email-error">
<span id="email-error" role="alert">
Please enter a valid email address (example: user@domain.com)
</span>
```
错误处理要求:指出出错字段;说明错误原因;提供纠正指引;字段上加 `aria-invalid`;通过实时区域或 `role="alert"` 播报错误。
必填字段:
```html
<label for="name">
Name <span aria-hidden="true">*</span>
<span class="sr-only">(required)</span>
</label>
<input type="text" id="name" required aria-required="true">
```
### 步骤7:图片、媒体与颜色对比
替代文本:
```html
<!-- Informative image -->
<img src="chart.png" alt="Q3 revenue increased 15% compared to Q2">
<!-- Decorative image -->
<img src="divider.png" alt="" role="presentation">
<!-- Complex image with extended description -->
<figure>
<img src="flowchart.png" alt="User registration process"
aria-describedby="flowchart-desc">
<figcaption id="flowchart-desc">
The registration process begins with email verification,
followed by profile creation, and ends with account activation.
</figcaption>
</figure>
```
视频与音频:
```html
<video controls>
<source src="video.mp4" type="video/mp4">
<track kind="captions" src="captions.vtt" srclang="en" label="English">
<track kind="descriptions" src="descriptions.vtt" srclang="en"
label="Audio descriptions">
</video>
```
最低对比度要求:
| 内容类型 | AA 最低比率 | AAA 增强比率 |
|----------|------------|--------------|
| 普通文本(< 18pt) | 4.5:1 | 7:1 |
| 大号文本(>= 18pt 或 14pt 加粗) | 3:1 | 4.5:1 |
| UI 组件与图形 | 3:1 | 不适用 |
绝不仅靠颜色传达信息:
```html
<!-- Bad: Color only indicates error -->
<input style="border-color: red">
<!-- Good: Color plus icon and text -->
<input aria-invalid="true" aria-describedby="error">
<span id="error">
<svg aria-hidden="true"><!-- Error icon --></svg>
Invalid email format
</span>
```
### 步骤8:动效与动画
尊重用户偏好:
```css
/* Reduce motion for users who prefer it */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
```
自动播放内容:避免自动播放视频或音频;提供暂停、停止或隐藏动态内容的控件;动画限制在 5 秒内或提供停止机制。
### 步骤9:测试方法论
**自动化测试**(约能发现 30-40% 的问题):axe DevTools(浏览器扩展页面分析)、WAVE(网页无障碍评估)、Lighthouse(Chrome DevTools 无障碍审计)、pa11y(命令行测试)。
**键盘测试**:断开或禁用鼠标;用 Tab/Shift+Tab 导航整个页面;验证所有交互元素可达;验证焦点指示器可见;测试所有快捷键;确认所有模态框和菜单可 Escape 退出。
**屏幕阅读器测试**:
| 平台 | 屏幕阅读器 | 浏览器 |
|------|-----------|--------|
| Windows | NVDA(免费) | Firefox, Chrome |
| Windows | JAWS | Chrome, Edge |
| macOS | VoiceOver | Safari |
| iOS | VoiceOver | Safari |
| Android | TalkBack | Chrome |
检查清单:所有图片有适当 alt 文本;标题体现页面结构;链接和按钮有描述性名称;表单字段有标签;错误消息被播报;动态内容更新被播报;表格有正确表头;自定义组件播报状态变化。
**视觉测试**:缩放 200% 验证无横向滚动;开启高对比度模式测试;禁用图片验证内容仍可理解;增大浏览器字号测试。
### 步骤10:常见组件模式
模态框:
```html
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirm Action</h2>
<p>Are you sure you want to proceed?</p>
<button type="button">Cancel</button>
<button type="button">Confirm</button>
</div>
```
要求:打开时焦点移入对话框;焦点被圈定在对话框内;Escape 键可关闭;关闭时焦点返回触发元素。
手风琴:
```html
<div class="accordion">
<h3>
<button aria-expanded="true" aria-controls="section1">
Section 1
</button>
</h3>
<div id="section1" role="region" aria-labelledby="section1-heading">
<!-- Content -->
</div>
</div>
```
导航菜单:
```html
<nav aria-label="Main">
<ul>
<li><a href="/" aria-current="page">Home</a></li>
<li>
<button aria-expanded="false" aria-haspopup="true">
Products
</button>
<ul>
<li><a href="/products/a">Product A</a></li>
<li><a href="/products/b">Product B</a></li>
</ul>
</li>
</ul>
</nav>
```
数据表格:
```html
<table>
<caption>Q3 Sales by Region</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Units Sold</th>
<th scope="col">Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">North</th>
<td>1,234</td>
<td>$45,678</td>
</tr>
</tbody>
</table>
```
## 参考资料
- [WCAG 2.1 快速参考](https://www.w3.org/WAI/WCAG21/quickref/)
- [WAI-ARIA 创作实践](https://www.w3.org/WAI/ARIA/apg/)
- [Inclusive Components](https://inclusive-components.design/)
- [A11y Project 清单](https://www.a11yproject.com/checklist/)使用说明
# 无障碍设计(WCAG 2.1 AA) WCAG 2.1 AA 合规实施指南:语义化 HTML、焦点管理、键盘导航、ARIA 模式与辅助技术测试,覆盖实现、审查与审计全场景。 ## 使用 ```text 帮我审查这个页面的无障碍合规性,按 WCAG 2.1 AA 标准列出问题。 ``` ```text 给这个自定义下拉组件加上正确的 ARIA 属性和键盘导航。 ``` ```text 我们的表单错误提示只用了红色边框,怎么改得更无障碍? ``` ## 工作原理 - **POUR 四原则评估**:可感知、可操作、可理解、健壮,作为所有无障碍决策的框架 - **语义化 HTML 优先**:ARIA 只做增强不做替代,六条硬性约束不可违反 - **十大实施步骤**:从场景约束、POUR 评估到焦点管理、ARIA 模式、表单、对比度、动效、测试与组件模式 - **三层测试法**:自动化工具(axe/WAVE/Lighthouse)+ 键盘走查 + 屏幕阅读器实测 ## 目录说明 - `SKILL.md` — 十步工作流与代码模式库
支持平台:Qoder · QoderWork · Claude · Codex 等 AI 编程助手