无障碍设计 (WCAG 2.2) 是做什么的?
本技能确保数字界面对于所有用户(包括使用屏幕阅读器、开关控制或键盘导航的用户)都是感知的、可操作的、可理解的和稳健的(POUR)。它专注于WCAG 2.2成功标准的技术实现。
使用时机
- 为 Web、iOS 或 Android 定义 UI 组件规范。
- 审计现有代码中的无障碍障碍或合规差距。
- 实现新的 WCAG 2.2 标准,如目标大小(最小)和焦点外观。
- 将高层设计需求映射到技术属性(ARIA 角色、特质、提示)。
核心概念
- POUR 原则:WCAG 的基础(Perceivable, Operable, Understandable, Robust)。
- 语义映射:使用原生元素而非通用容器,以提供内置无障碍支持。
- 无障碍树:辅助技术实际“读取”的 UI 表示。
- 焦点管理:控制键盘/屏幕阅读器光标的顺序和可见性。
- 标签与提示:通过
aria-label、accessibilityLabel和contentDescription提供上下文。
工作原理
第一步:标识组件角色
确定功能目的(例如:这是一个按钮、链接还是标签页?)。在求助于自定义角色之前,尽量使用最语义化的原生元素。
第二步:定义感知属性
- 确保文本对比度达到 4.5:1(标准)或 3:1(大文本/UI)。
- 为非文本内容(图片、图标)添加替代文本。
- 实现响应式重排(放大至 400% 而不丢失功能)。
第三步:实现可操作控制
- 确保最小 24x24 CSS 像素 的目标大小(WCAG 2.2 SC 2.5.8)。
- 验证所有交互元素可通过键盘访问,并具有可见的焦点指示器(SC 2.4.11)。
- 为拖拽操作提供单指针替代方案。
第四步:确保逻辑可理解
- 使用一致的导航模式。
- 提供描述性的错误信息和更正建议(SC 3.3.3)。
- 实现“重复输入”(SC 3.3.7),防止重复询问相同数据。
第五步:验证稳健兼容性
- 使用正确的名称、角色、值模式。
- 对于动态状态更新,实现
aria-live或活动区域。
无障碍架构图
flowchart TD
UI["UI 组件"] --> Platform{平台?}
Platform -->|Web| ARIA["WAI-ARIA + HTML5"]
Platform -->|iOS| SwiftUI["无障碍特质 + 标签"]
Platform -->|Android| Compose["语义 + contentDescription"]
ARIA --> AT["辅助技术(屏幕阅读器、开关)"]
SwiftUI --> AT
Compose --> AT
跨平台映射
| 特性 | Web (HTML/ARIA) | iOS (SwiftUI) | Android (Compose) |
|---|---|---|---|
| 主要标签 | aria-label / <label> | .accessibilityLabel() | contentDescription |
| 辅助提示 | aria-describedby | .accessibilityHint() | Modifier.semantics { stateDescription = ... } |
| 操作角色 | role="button" | .accessibilityAddTraits(.isButton) | Modifier.semantics { role = Role.Button } |
| 实时更新 | aria-live="polite" | .accessibilityLiveRegion(.polite) | Modifier.semantics { liveRegion = LiveRegionMode.Polite } |
示例
Web:无障碍搜索
<form role="search">
<label for="search-input" class="sr-only">搜索产品</label>
<input type="search" id="search-input" placeholder="搜索..." />
<button type="submit" aria-label="提交搜索">
<svg aria-hidden="true">...</svg>
</button>
</form>
iOS:无障碍操作按钮
Button(action: deleteItem) {
Image(systemName: "trash")
}
.accessibilityLabel("删除项目")
.accessibilityHint("永久从此列表中移除该项目")
.accessibilityAddTraits(.isButton)
Android:无障碍切换开关
Switch(
checked = isEnabled,
onCheckedChange = { onToggle() },
modifier = Modifier.semantics {
contentDescription = "启用通知"
}
)
应避免的反模式
- Div-按钮:使用
<div>或<span>处理点击事件,但未添加角色和键盘支持。 - 纯颜色含义:仅通过颜色变化指示错误或状态(例如,将边框变红)。
- 模态框焦点未限制:模态框未能限制焦点,导致键盘用户可在模态框打开时导航背景内容。焦点必须被限制,并且可通过
Escape键或明确的关闭按钮退出(WCAG SC 2.1.2)。 - 冗余替代文本:在替代文本中使用“图片...”或“图像...”(屏幕阅读器已宣布角色“图像”)。
最佳实践检查清单
- 交互元素符合 24x24px(Web)或 44x44pt(原生)目标大小。
- 焦点指示器清晰可见且高对比度。
- 模态框打开时限制焦点,并在关闭时干净释放(
Escape键或关闭按钮)。 - 下拉菜单和弹出面板关闭时将焦点恢复到触发元素。
- 表单提供基于文本的错误建议。
- 所有仅含图标的按钮都有描述性文本标签。
- 文本缩放时内容正确重排。
参考资源
相关技能
frontend-patternsdesign-systemliquid-glass-designswiftui-patterns