Skip to content
返回设计中心

无障碍与 WCAG 2.2 合规

构建满足 WCAG 2.2 AA 合规的无障碍 Web 界面的实用指南。

无障碍入门

为什么

无障碍界面排斥了 15% 的残障用户,产生法律风险(ADA、EAA),并降低 SEO 因为搜索引擎无法解析 ARIA 误用的内容。无障碍不是可选项。

WebAIM Million 2024 报告发现 96.3% 的首页存在可检测的 WCAG 失败。2023 年 ADA 相关诉讼超过 4,500 起,使无障碍成为法律和伦理必需,而非可有可无。

何时使用

始终。无障碍必须从第一个组件开始内建,而非上线前补加。如果现有 UI 未考虑无障碍,应立即审计。

如何做

1. 语义 HTML — 使用 <button>、<nav>、<main>、<label> 而非 <div onClick> 2. 键盘导航 — 每个可交互元素必须可聚焦可操作 - Tab 顺序遵循视觉顺序(不用正 tabindex) - Enter/Space 激活按钮,Escape 关闭对话框 3. ARIA — 仅在语义 HTML 不足时使用 - aria-label 用于纯图标按钮 - aria-expanded 用于可折叠区域 - role="dialog" + aria-modal="true" 用于模态框 4. 颜色对比 — 文本最低 4.5:1,大文本和 UI 组件 3:1 5. 焦点管理 — 模态框内陷阱焦点,关闭时恢复焦点 6. 测试 — CI 中 axe-core,用 NVDA/VoiceOver 手动屏幕阅读器测试

示例

// 无障碍模态对话框 function Modal({ open, onClose, title, children }: ModalProps) { const dialogRef = useRef<HTMLDivElement>(null); useEffect(() => { if (!open) return; // 陷阱焦点 + 关闭时恢复 const previouslyFocused = document.activeElement as HTMLElement; dialogRef.current?.focus(); const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); // 焦点陷阱逻辑... }; document.addEventListener("keydown", handleKeyDown); return () => { document.removeEventListener("keydown", handleKeyDown); previouslyFocused?.focus(); // 恢复焦点 }; }, [open, onClose]); if (!open) return null; return ( <div role="dialog" aria-modal="true" aria-labelledby="modal-title" ref={dialogRef} tabIndex={-1} className="fixed inset-0 z-50"> <h2 id="modal-title">{title}</h2> {children} <button onClick={onClose} aria-label="关闭对话框">X</button> </div> ); }

常见问题

  • ⚠在 <div> 上用 role='button' — 应使用真正的 <button> 以支持键盘
  • ⚠aria-label 覆盖可见文本 — 屏幕阅读器丢失按钮文本内容
  • ⚠正 tabindex(tabindex='1')— 破坏自然 tab 顺序,用 tabindex='-1' 或 '0'
  • ⚠缺少 focus-visible 样式 — 键盘用户看不到焦点位置

最佳实践

  • ✓优先语义 HTML 而非 ARIA — ARIA 是最后手段,不是首选
  • ✓CI 中运行 axe-core — 新违规时构建失败,而非仅警告
  • ✓用真实屏幕阅读器测试 — 自动化工具最多发现 40% 的问题
  • ✓使用 prefers-reduced-motion 媒体查询 — 为前庭敏感者禁用动画

常见问题解答

每个元素都需要 ARIA 才能无障碍吗?

不需要——优先语义 HTML(<button>、<nav>、<label>)。ARIA 是 HTML 无法表达模式时的最后手段。滥用 ARIA 往往更糟。

WCAG 2.2 应目标哪个级别?

AA 是法律和实践基线(ADA、EAA 合规)。全产品达 AA,关键流程如结账可行时达 AAA。

自动化工具之外如何测试无障碍?

axe-core 约发现 40% 问题。其余用真实屏幕阅读器(NVDA/VoiceOver)和纯键盘导航测试——每个可交互元素必须可达可操作。

颜色对比度需要多少?

普通文本 4.5:1,大文本(≥18px 或 14px 粗体)和 UI 组件 3:1。在设计工具里用对比检查器,别只靠目测。

模态框如何管理焦点?

打开时焦点陷阱在模态内,关闭时恢复到触发元素。用 aria-modal='true' 并监听 Escape 关闭。