调研探索
开发或审查 Web 界面时,需要满足无障碍标准…
适用于任何前端项目的无障碍实现与审查,覆盖键盘导航、焦点管理、表单错误、动态内容与结构语义。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
开发或审查 Web 界面时,需要满足无障通用
解决思路
- 优先利用平台/原生能力:原生元素自带键盘支持,真实标签会自行公告,可见焦点环只需一条 CSS 规则。
- 每个修复都写进项目的样式系统,并使用下面给出的精确值,而不是看起来相似的替代值。
- 审查分两轮:先仅键盘,确保每个流程无需鼠标即可完成;再屏幕阅读器,确保每个控件都声明名称、角色和状态。
- 不确定时采用平台默认而非自定义重建,并移除 ARIA 而不是添加 ARIA。
- 对比度测量和颜色修复交给 `better-colors`;文本大小和 iOS 输入缩放交给 `better-typography`;空间 RTL 布局交给 `better-layout`。
- 原生元素优先:ARIA 第一条规则是存在原生元素时不要用 ARIA。操作用 `<button>`,导航用 `<a href>`,绝不用 `<div onClick>`。
- 真实链接必须支持 Cmd/Ctrl/中键点击。
- 没有 ARIA 比坏 ARIA 好;参见 `semantics-and-aria.md` 了解 landmarks、button-vs-link 和 disabled 状态。
- 样式化 `:focus-visible`,而不是裸 `:focus`,使键盘用户获得焦点环而鼠标用户通常没有。
- 优先使用浏览器未修改的焦点指示器。
- 自定义焦点环需要项目 focus token 或另一个显式颜色。
- 验证整个焦点指示器与其交叉的每一种相邻颜色(包括 `currentColor`)。
- 使用至少 `2px` 实线周长或等效可见区域。
- 绝不在没有验证替代方案的情况下使用 `outline: none`,并在 forced-colors 模式下保留系统颜色;配方在 `focus-and-keyboard.md`。
- 每个指针交互都需要键盘路径。
- 遵循 ARIA APG 模式:Escape 关闭覆盖层,方向键在复合组件内移动,Tab 在组件之间移动,Enter 和 Space 激活。
- 仅使用 `tabindex="0"` 加入自然 Tab 顺序,使用 `tabindex="-1"` 进行程序化聚焦;正值会破坏该顺序。
- 复合组件使用 roving tabindex,活动项为 `0`,其他所有项为 `-1`。
- 模态框在背景内容上设置 `inert`,打开时将焦点移入内部,关闭时将焦点返回触发器。
- 添加 `overscroll-behavior: contain`,使背景内容不滚动。
- WCAG 2.5.8 的 Level AA 基线是 24×24 CSS 像素目标,或其间距、等效控件、内联、用户代理和必要例外之一。
- 在密度允许的情况下,触控目标达到 44×44px,桌面达到 40×40px。
- 当可见元素应保持较小时,用伪元素扩展点击区域。
- 绝不让扩展的点击区域重叠。
- 给装饰层 `pointer-events: none`,使光晕不会吞掉本应属于下方控件的点击;尺寸和碰撞规则在 `hit-areas.md`。
- 每个输入都有 `<label for>` 或包裹的 `<label>`;占位符绝不是标签。
- 标签和控件共享一个点击目标,复选框与其文本之间没有死区。
- 添加带有有意义 `name` 的 `autocomplete`,以及能唤起正确键盘的 `type` 和 `inputmode`。
- 绝不要阻止粘贴;用户会粘贴密码和一次性验证码;参见 `forms.md`。
- 保持提交启用,直到请求开始,然后用 spinner 和原始标签禁用。
- 提交时验证;将失败字段标记为 `aria-invalid="true"`,将 `aria-describedby` 指向内联错误文本,并聚焦第一个无效字段。
- 当控件确实不可用时使用原生 `disabled`。
- 仅当控件应保持可聚焦时,才使用 `aria-disabled="true"`,然后在代码中阻止指针、键盘和表单行为,并显式样式化该状态。
- 仅图标按钮需要描述性的 `aria-label`。
- 可见标签文本必须出现在可访问名称中。
- 装饰元素获得 `aria-hidden="true"`,绝不放在可聚焦元素上。
- 状态需要冗余提示:颜色旁边的图标、文本或下划线。
- 确定适用哪项 WCAG 对比度要求,然后使用 `better-colors` 测量渲染后的配对。
- 当对比度失败时,报告配对和它未满足的要求,除非被要求,否则不要改动颜色。
- 将动效包裹在 `@media (prefers-reduced-motion: no-preference)` 中,使其成为可选加入。
- 在减少动效下,将滑动和缩放替换为透明度交叉淡入淡出,并完全移除视差和自动播放。
- 无论 `prefers-reduced-motion` 偏好如何,两条规则都成立:自动播放媒体需要可见的暂停控件;带操作或错误的 toast 保持到被关闭;参见 `motion-and-zoom.md`。
- `aria-describedby` 承载字段特定的验证。
- polite live region (`role="status"`) 承载与控件无关的非紧急更新,例如 toast 和结果计数。
- `role="alert"` 承载紧急的无关错误,仅此而已。
- 重复的 polite 公告需要一个在其文本更新之前渲染的稳定空区域。
- 动态插入的 alert 支持情况各异,因此在你目标屏幕阅读器上测试它们;参见 `screen-readers.md`。
- 装饰性图像获得 `alt=""`。
- 信息性图像描述含义。
- 功能性图像描述动作:搜索图标按钮是 `alt="Search"`,而不是 `alt="magnifying glass"`。
- 使用描述其分区并形成连贯大纲的标题。
- 给页面一个 `<h1>`,并在其下嵌套级别而不跳过。
- 暴露一个可见的主要 `<main>` landmark。
- 当重复导航或 chrome 位于其之前时,使 "Skip to content" 链接成为第一个可聚焦元素。
- 锚定标题获得 `scroll-margin-top`。
- 页面必须在 200% 缩放和 320px 宽度重排时工作,而不出现水平滚动。
- 在文本容器上使用 `min-height` 而不是固定 `height`。
- 在适合代码库的地方优先使用 `rem` 断点,绝不让 viewport meta 限制读者可缩放的程度。
- 完成前修复常见错误:自定义焦点颜色被假定到处可用 -> 针对每种相邻颜色和 forced-colors 模式进行验证。
- 完成前修复常见错误:重复的 polite 更新公告不一致 -> 保持稳定的空状态区域并更新其文本。
- 完成前修复常见错误:常规 toast 使用 `assertive` live region -> 使用 `polite`;将 `assertive` 保留给错误。
- 完成前修复常见错误:在可聚焦元素上 `aria-hidden="true"` -> 移除它或使元素不可聚焦。
- 完成前修复常见错误:提交保持禁用直到表单有效 -> 保持启用;提交时验证并聚焦第一个错误。
- 完成前修复常见错误:触摸设备上点击后 hover 样式卡住 -> 用 `@media (hover: hover)` 门控 hover 样式。
- 完成前修复常见错误:原生 `disabled` 控件上的 tooltip -> 在其旁边放文本,或使用 `aria-disabled` 使其保持可聚焦。
- 报告严重性:`HIGH` 阻止任务、对辅助技术隐藏内容或造成系统性失败;`MEDIUM` 使交互显著更难;`LOW` 是孤立打磨。
- 验证时无浏览器则检查每个交互元素上的可访问名称、非原生控件上的键盘处理程序、焦点样式、`prefers-reduced-motion` 防护和绑定到输入的 form labels。
- 验证时有浏览器则按顺序 Tab 流程,从可访问性树读取计算出的名称和角色,确认每个停靠点都有可见焦点指示器,并运行自动审计。
- 将每个无法运行的检查报告为 `Not verified`。
- 按违反的原则分组发现,按严重程度排序,每个根因一行,列出其出现的每个位置:`| Severity | Location | Before | After | Why |`。
- `Location` 是 `path/to/file:line`;`Why` 命名原则和用户影响。
- 当任何 `HIGH` 仍存在时以 `Block` 结束,否则 `Approve`,将其余留在表中作为待办工作。
- 绝不 `Approve` 你没有检查的覆盖范围。
- 没有可报告内容时,说明 "No actionable accessibility findings" 并报告验证。
适用边界 · 注意事项
- 不处理对比度测量与颜色修复,这些交给 `better-colors`。
- 不处理文本尺寸与 iOS 输入缩放,这些交给 `better-typography`。
- 不处理空间 RTL 布局,这些交给 `better-layout`。