跳转至

无障碍(WCAG 2.2)

本技能确保数字界面对所有用户(包括使用屏幕阅读器、开关控制和键盘导航的用户)都是可感知、可操作、可理解且健壮的(POUR)。它专注于 WCAG 2.2 成功准则的技术实现。

使用场景

  • 为 Web、iOS、Android 定义 UI 组件规范。
  • 审计现有代码中的无障碍障碍或合规差距。
  • 实现 Target Size(最小)和 Focus Appearance 等新的 WCAG 2.2 准则。
  • 将高层设计需求映射到技术属性(ARIA 角色、特征、提示)。

核心概念

  • POUR 原则:WCAG 的基础(可感知、可操作、可理解、健壮)。
  • 语义映射:使用原生元素而非通用容器,以提供内置无障碍支持。
  • 无障碍树:辅助技术实际“读取”的 UI 表示。
  • 焦点管理:控制键盘和屏幕阅读器光标的顺序与可见性。
  • 标签与提示:通过 aria-label、accessibilityLabel、contentDescription 提供上下文。

工作原理

步骤 1:确定组件角色

确定功能目的(例如:这是按钮、链接还是选项卡?)。在依赖自定义角色之前,使用可用的最具语义化的原生元素。

步骤 2:定义可感知属性

  • 确保文本对比度达到 4.5:1(常规)或 3:1(大文本/UI)。
  • 为非文本内容(图像、图标)添加文本替代。
  • 实现响应式重排(在不损失功能的情况下支持最大 400% 缩放)。

步骤 3:实现可操作控件

  • 确保目标尺寸最小为 24x24 CSS 像素(WCAG 2.2 SC 2.5.8)。
  • 确保所有可交互元素均可通过键盘到达,并具有可见的焦点指示器(SC 2.4.11)。
  • 为拖拽操作提供单指针替代方式。

步骤 4:确保可理解的逻辑

  • 使用一致的导航模式。
  • 提供描述性错误消息和修正建议(SC 3.3.3)。
  • 实现“防止冗余输入”,避免重复请求相同数据(SC 3.3.7)。

步骤 5:验证健壮兼容性

  • 使用正确的 Name, Role, Value 模式。
  • 为动态状态更新实现 aria-live 或实时区域。

无障碍架构图

flowchart TD
  UI["UI コンポーネント"] --> Platform{プラットフォーム?}
  Platform -->|Web| ARIA["WAI-ARIA + HTML5"]
  Platform -->|iOS| SwiftUI["アクセシビリティトレイト + ラベル"]
  Platform -->|Android| Compose["セマンティクス + コンテンツ説明"]

  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 }

示例

<form role="search">
  <label for="search-input" class="sr-only">Search products</label>
  <input type="search" id="search-input" placeholder="Search..." />
  <button type="submit" aria-label="Submit Search">
    <svg aria-hidden="true">...</svg>
  </button>
</form>

iOS:无障碍操作按钮

Button(action: deleteItem) {
    Image(systemName: "trash")
}
.accessibilityLabel("Delete item")
.accessibilityHint("Permanently removes this item from your list")
.accessibilityAddTraits(.isButton)

Android:无障碍切换

Switch(
    checked = isEnabled,
    onCheckedChange = { onToggle() },
    modifier = Modifier.semantics {
        contentDescription = "Enable notifications"
    }
)

应避免的反模式

  • Div 按钮:在未添加角色和键盘支持的情况下,将 <div> 或 <span> 用于点击事件。
  • 仅用颜色表达含义:仅通过颜色变化表示错误或状态(例如:将边框变为红色)。
  • 模态焦点未封闭:在未捕获焦点的模态框中,键盘用户可以在模态框打开期间导航背景内容。焦点必须被捕获_且_能够通过 Escape 键或明确的关闭按钮退出(WCAG SC 2.1.2)。
  • 冗余替代文本:在 alt 文本中使用“一张……的图片”或“……的图片”(屏幕阅读器已经会播报“图像”角色)。

最佳实践检查清单

  • [ ] 可交互元素满足 24x24px(Web)或 44x44pt(原生)的目标尺寸。
  • [ ] 焦点指示器清晰可见且具有高对比度。
  • [ ] 模态框在打开期间捕获焦点,并在关闭时干净地释放焦点(Escape 键或关闭按钮)。
  • [ ] 下拉菜单和菜单在关闭时将焦点返回到触发元素。
  • [ ] 表单提供基于文本的错误建议。
  • [ ] 仅图标按钮具有描述性文本标签。
  • [ ] 文本缩放时,内容能够适当重排。

参考资料

  • frontend-patterns
  • design-system
  • liquid-glass-design
  • swiftui-patterns

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC