关于 a11y
面向界面开发的无障碍实践 Skill,适用于设计和实现网页 UI 的开发者。内容涵盖语义 HTML、键盘操作、焦点、表单、对比度、动效和页面结构,并提供快速检查流程。
主要功能
- 01优先采用语义 HTML
- 02定义可访问名称与键盘行为
- 03规范焦点、ARIA 与对话框
- 04覆盖表单、对比度和动效
- 05提供结构、缩放与时限指导
- 06包含五分钟无障碍检查
适用场景
- 01设计键盘可操作的界面
- 02检查表单标签与错误提示
- 03改善对话框焦点管理
- 04验证缩放、对比度与减少动效
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ paragonhq/ stealth-skills --skill a11y安装后在 Claude Code 中输入/a11y确认已加载。
详细介绍
a11y
无障碍界面并非与优秀界面各自独立。这里几乎每条规则,也会让使用鼠标且视力正常的人获得更好的体验。把它当作一门手艺,而不是合规要求。
优先使用 HTML
元素本身就承载着行为。请使用合适的元素:
| 需求 | 使用 | 不要使用 |
|---|---|---|
| 执行某项操作 | <button type="button"> | <div onClick> |
| 跳转到其他位置 | <a href> | 调用 router.push 的 <button> |
| 列表 | 使用 <li> 的 <ul>/<ol> | div |
| 表单 | 带有 <button type="submit"> 的 <form> | 在表单外部的按钮上使用 onClick |
| 复选框、单选按钮、开关 | <input type="checkbox">,或在按钮上使用 role="switch" | 自定义 div |
| 带标题的区块 | <section aria-labelledby> | 带有粗体段落的 div |
| 强调 | <strong>、<em> | <b>、<i> 或带有 font-weight 的 span |
| 对话框 | <dialog> 或带有 role="dialog" 的原语 | 固定定位的 div |
原生元素会自动提供键盘行为、焦点、角色和名称。每个自定义替代方案都必须自行补齐这四项。
名称
每个控件都必须有可访问名称。优先顺序如下:
- 控件中的可见文本(
<button>保存更改</button>)。 - 可见的
<label for>(用于输入框)。 - 指向可见文本的
aria-labelledby。 - 仅对纯图标控件使用
aria-label,并说明控件的作用,而不是图标是什么(“复制链接”,而不是“剪贴板图标”)。
图像:使用能说明图像所传达内容的 alt,装饰性图像则使用 alt=""。带标签控件内的图标应设为 aria-hidden。
名称在当前上下文中必须唯一。列表中有五个“编辑”按钮时,应为它们标明“编辑 Q3 报告”,可以显示在界面上,也可以通过 aria-label 提供。
键盘
- 所有交互元素都能按视觉顺序通过 Tab 访问。
tabindex只能是0或-1,绝不能为正数。 - 自定义控件应遵循其角色对应的 ARIA 模式:在菜单、标签页、列表框和单选按钮组内使用方向键;按 Tab 离开控件。
- 按 Escape 只关闭最顶层的界面层。
- 对话框打开时,焦点移入其中,并在打开期间保持在其中;关闭时,焦点返回触发控件。
- 模态框后面的内容应设为
inert。 - 跳过链接应是第一个可聚焦元素,并在获得焦点时显示。
- 焦点位于文本输入框时,单键快捷键不应触发;组合键快捷键不得与浏览器快捷键冲突。
- 复合控件应使用 roving tabindex 或
aria-activedescendant,确保每个控件只占一个 Tab 停靠点。
可见焦点
:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }
- 在任何表面颜色上都清晰可见。请在最深和最浅的颜色上测试。
- 与元素的圆角相匹配。
- 除非提供替代样式,且该样式与元素及其背景的对比度均至少为 3:1,否则绝不能使用
outline: none。 - 作为链接的行和卡片,应让整行显示焦点,而不只是文本。
谨慎使用 ARIA
ARIA 的第一条规则:如果 HTML 能实现,就不要使用 ARIA。除此之外:
- 在任何可展开内容的触发控件上设置
aria-expanded,并用aria-controls指向该内容。 - 在当前活动的导航链接上设置
aria-current="page";页内导航使用aria-current="location"。 - 切换按钮使用
aria-pressed;开关和复选框使用aria-checked;标签页和选项使用aria-selected。 - 正在加载的区域使用
aria-busy;禁用的控件必须保持可聚焦时,使用aria-disabled。 - 使用
aria-describedby将输入框与其错误提示和说明关联起来。 - 在播报 Toast 和状态信息的区域上设置
aria-live="polite"。只有会阻断操作的错误才使用assertive。 - 在装饰性图标、视觉上的重复内容(例如,为了动画效果而将单词拆分到多个 span 中时,应在父元素上设置
aria-label)以及背景遮罩上设置aria-hidden="true"。 - 如果可以使用按钮,就绝不要在 div 上设置
role="button"。没有角色的div上绝不要使用aria-label。
表单
- 每个字段都有可见标签。占位符只是提示。
- 必填字段会标明,并且只解释一次标记的含义。
- 错误:在失焦或提交后显示,位于字段下方,通过
aria-describedby关联;提交时将焦点移至第一个无效字段。 - 错误文本用文字说明问题及修复方法;颜色和图标作为辅助,绝不取代文字。
- 单选框和复选框组放在带有
<legend>的<fieldset>中。 - 设置
autocomplete,让浏览器和辅助技术能够自动填充。 - 在任何字段中按 Enter 都能提交表单。
颜色和对比度
- 文本对比度为 4.5:1;大号文本和 UI 边界为 3:1;两种主题均须满足。
- 颜色绝不是唯一的信号:状态配有图标或文字;行内文本中的链接带下划线;图表带有纹理或标签。
- 只有在不依赖阅读的情况下,占位符和禁用文本的对比度才可以低于 4.5:1。
- 检查焦点环和选中色与每种表面的对比度。
prefers-contrast: more会将边框颜色提升为--fg-2,并移除半透明效果。forced-colors: active(Windows 高对比度):为依赖背景色的控件添加边框;焦点使用outline;不使用有语义作用的background-image。
动效
prefers-reduced-motion: reduce:将过渡和动画缩减至接近于零,关闭平滑滚动和视差效果,暂停自动播放的视频,但不隐藏任何内容。原本会以动画进入的元素直接显示。- 每秒闪烁不超过三次。
- 时长超过五秒的自动播放动效必须提供暂停控件。
结构
- 每页只有一个
h1;标题按顺序排列,不跳级;每个屏幕阅读器用户可能想要跳转到的区域都有标题。 - 地标:一个
main、header、footer、nav(有多个时需添加标签)、aside、search。 - 列表使用列表元素。基于行的 UI 使用带有
aria-label的<ul>。 - 表格使用带有
<th scope>的<table>,或使用角色设置正确的网格。不要使用 div。 - 在文档以及任何使用其他语言的段落上设置
lang。 - DOM 中的阅读顺序与视觉顺序一致。CSS
order和flex-direction: row-reverse会破坏这一点。
尺寸和缩放
- 根据 WCAG,目标尺寸至少为 24px;实际触控目标为 44px。
- 页面在浏览器缩放至 200% 和宽度为 320px 时均能正常使用,不会出现水平滚动或内容丢失。
- 可增大文本间距(
line-height 1.5、letter-spacing 0.12em、word-spacing 0.16em),而不会发生裁切。 - 绝不禁用双指缩放。
计时
- Toast 至少显示 5 秒;存在操作时显示更久,并在悬停和获得焦点时暂停。
- 会话超时前要发出警告,并留出延长时间。
- 使用过程中不要求用户在限定时间内作出响应。
五分钟测试
- 拔掉鼠标。按 Tab 遍历屏幕。能看到当前焦点位置吗?能完成所有操作吗?
- 开启 VoiceOver(⌘F5)或 NVDA。按标题导航(VO+⌘+H)。标题能描述页面内容吗?按 Tab 聚焦控件:每个控件是否都能读出其角色、名称和状态?
- 打开对话框。焦点是否位于其中?按 Escape 能关闭对话框并将焦点移回原处吗?
- 缩放至 200%。页面还能正常使用吗?
- 开启减少动效。是否有内容消失?
- 运行 axe。修复所有“严重”和“关键”问题。阅读“中等”问题;大多数都确实需要处理。
不易访问的 UI 特征
| 特征 | 修复方法 |
|---|---|
div onClick | button |
outline: none | :focus-visible 焦点环 |
| 没有名称的图标按钮 | aria-label |
| 将占位符用作标签 | 可见标签 |
| 仅用红色文本显示错误 | 图标 + 文本 + aria-describedby |
| 没有焦点陷阱的模态框 | 对话框基础组件,将后方内容设为 inert |
| 自定义选择框 | 原生 <select> 或列表框基础组件 |
| 仅悬停时可见的操作提示 | 始终可见,或聚焦时也可见 |
| 减少动效时隐藏内容的动效 | 内容保持可见,移除动效 |
| 仅用颜色表示的状态 | 图标或文字 |
来自目录
- Sara Soueidan — 由实践者撰写的无障碍设计和 SVG 内容。
- ARIA Authoring Practices — 每种模式对应的键盘交互和角色规范。
- Inclusive Components — 从一开始就注重无障碍设计的组件。
- axe、Polypane — 在已打开的浏览器中进行测试。
- Nielsen Norman Group — 关于可用性的研究,与此列表几乎完全重合。
- 更多内容请见 stealth.pm/tools。
评论
支持 Markdown