关于 better-accessibility
better-accessibility 是用于检查和修复界面无障碍问题的技能,面向开发者和界面审查者。它涵盖语义、键盘与屏幕阅读器交互、表单、动态效果和缩放,并将问题对应到 WCAG 2.2 A 级或 AA 级标准。
主要功能
- 01检查语义和无障碍名称
- 02核验键盘操作路径与可见焦点
- 03审查表单标签和错误播报
- 04覆盖动态效果偏好与缩放
- 05按 WCAG 标准归类问题
适用场景
- 01检查界面流程能否仅用键盘完成
- 02核验屏幕阅读器播报的名称、角色和状态
- 03发现表单标注与验证问题
- 04评估减少动态效果和缩放行为
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jakubkrehel/ skills --skill better-accessibility安装后在 Claude Code 中输入/better-accessibility确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
focus-and-keyboard.mdforms.mdhit-areas.mdmotion-and-zoom.mdscreen-readers.mdsemantics-and-aria.mdagents/openai.yaml详细介绍
无障碍
此技能会检查并修复语义、键盘与焦点行为、无障碍名称、表单、公告、动效和缩放。它会针对每项问题指出违反的 WCAG 标准,并使用项目的样式系统编写修复方案。
检查分为两轮。第一轮仅使用键盘,确保每个流程都能在不使用鼠标的情况下完成。第二轮使用屏幕阅读器,确保每个控件都会播报名称、角色和状态。如有疑问,优先采用平台默认行为,而不是自定义重做;宁可移除 ARIA,也不要添加。
对比度测量和颜色修复归 better-colors 负责。文本大小、iOS 输入缩放和语言元数据归 better-typography 负责。目标间距和空间方向 RTL 归 better-layout 负责。标签、错误和替代文本措辞归 better-writing 负责。动画方案、悬停样式和滚动限制归 better-ui 负责。
标准,而非惯例
每项问题都应引用 WCAG 2.2 A 级或 AA 级标准编号,或指出辅助技术用户无法完成的具体任务。其他内容都只是建议,绝不能标为 HIGH。这包括 AAA 级标准、APG 惯例、只使用一个 <h1> 且标题层级不跳级的结构,以及 44px 和 40px 的目标尺寸。下方列出的标准阈值是精确要求。更大的目标尺寸属于经验法则,因此应保留已有且实用的界面密度。
优先使用原生元素
ARIA 的首要规则:有原生元素时,不要使用 ARIA。操作使用 <button>,导航使用 <a href>,绝不要用 <div onClick>。真正的链接必须支持 Cmd/Ctrl/鼠标中键点击。地标和按钮与链接的区别请参阅 semantics-and-aria.md。
禁用即不可用
控件确实不可用时,使用原生 disabled。只有在控件仍应可获得焦点时才使用 aria-disabled="true",并在代码中阻止指针、键盘和表单行为,同时明确设置该状态的样式。相关规则见 semantics-and-aria.md。
可见焦点环
设置 :focus-visible 的样式,而非直接设置 :focus。键盘用户会看到焦点环,而鼠标用户通常不会。优先使用未经修改的浏览器指示器。
自定义焦点环必须使用项目的焦点令牌或其他明确指定的颜色。根据 1.4.11,其与经过的每种相邻颜色(包括 currentColor)之间的对比度都必须达到 3:1。根据 AAA 级标准 2.4.13,2px 实线轮廓且对比度变化达到 3:1 即可。没有经过验证的替代方案时,绝不要使用 outline: none;在强制颜色模式下保留系统颜色。
获得焦点的元素绝不能被粘性页眉、页脚或横幅完全遮挡(2.4.11)。为滚动容器增加与粘性界面高度相当的内边距,该修复归 better-layout 负责。方案见 focus-and-keyboard.md。
完整的键盘支持
每种指针交互都必须提供键盘操作路径。遵循 ARIA APG 模式:Escape 关闭覆盖层,方向键在复合控件内移动,Tab 在控件之间移动,Enter 和 Space 激活按钮。
仅使用 tabindex="0" 将元素加入自然 Tab 顺序,使用 tabindex="-1" 设置程序化焦点。正数会破坏该顺序。复合控件使用 roving tabindex:当前活动项设为 0,其他项设为 -1。对于必须将焦点留在输入框中的情况(如组合框),改用 aria-activedescendant。各类控件的按键映射见 focus-and-keyboard.md。
限制并恢复焦点
优先使用通过 showModal() 打开的 <dialog>,它会让背景变为 inert,并处理 Escape。自定义覆盖层应在背景上设置 inert,并在自身设置 role="dialog" 和 aria-modal="true"。无论采用哪种方式,打开时都应将焦点移入其中,关闭时将焦点还给触发控件。
客户端路由切换不会自动重置任何内容。更新 document.title,并将焦点移至新视图的 <h1> 或 <main>。这两种方案都见 focus-and-keyboard.md。
最小点击区域
WCAG 2.5.8 的 AA 级基准是 24×24 CSS 像素的目标区域,或符合其例外情况。触控场景下尽量达到 44×44px;桌面场景下,在空间允许时尽量达到 40×40px。如果可见元素需要保持较小,可用伪元素扩展点击区域。
扩展后的点击区域绝不能重叠。为装饰层设置 pointer-events: none,避免光效吞掉本应触发下方控件的点击。
每种拖动交互都需要提供单指操作的替代方式,例如可对同一项目进行排序或移动的按钮或菜单(2.5.7)。尺寸、例外情况和碰撞规则见 hit-areas.md。
为每个控件添加标签并指定类型
每个输入框都要有 <label for>,或用 <label> 包裹。占位符不能代替标签。标签和控件应共用一个点击区域,复选框与其文本之间不能有无法点击的空隙。
添加有效的 autocomplete 令牌和描述性 name 属性,并设置合适的 type 和 inputmode,以调出正确的键盘。绝不能禁止粘贴;用户会粘贴密码和一次性验证码。参见 forms.md。
会播报的错误
在提交时验证表单;绝不要通过禁用提交按钮来阻止无效表单提交。将未通过验证的字段标记为 aria-invalid="true",让 aria-describedby 指向行内错误文本,并将焦点移至第一个无效字段。请求进行期间的提交行为见 forms.md。
为所有控件提供可访问名称
仅含图标的按钮需要描述性 aria-label。可见标签文本必须包含在可访问名称中。装饰元素应设置 aria-hidden="true",绝不能将其用于可聚焦元素。
颜色之外再提供一种提示
状态需要有冗余提示:除颜色外,还要搭配图标、文本或下划线(1.4.1)。
本技能用于判断适用哪项对比度要求:
| 准则 | 适用对象 | 最低值 |
|---|---|---|
| 1.4.3 AA | 文本 | 4.5:1 |
| 1.4.3 AA | 大号文本,至少为 24px 或 18.67px 粗体 | 3:1 |
| 1.4.11 AA | UI 组件边界、状态和有意义的图形 | 3:1 |
非活动控件和徽标不受此要求约束。使用 better-colors 测量渲染后的颜色组合。如果未达标,请报告该颜色组合及未满足的准则;除非用户要求,否则不要改动颜色。
遵循 prefers-reduced-motion
将动画包在 @media (prefers-reduced-motion: no-preference) 中,使其仅在用户未启用减少动态效果时运行。减少动态效果时,将滑动和缩放替换为不透明度交叉淡化,并彻底停用视差效果和自动播放。参见 motion-and-zoom.md。
用户需要的信息不能依赖计时器
任何自行移动、闪烁或更新且持续超过 5 秒的内容,都需要提供可见的暂停控件(2.2.2)。包含操作或错误信息的 Toast 应一直显示,直到用户将其关闭。规则见 motion-and-zoom.md。
播报动态内容
三种机制,各司其职。aria-describedby 用于字段专属的验证信息。礼貌播报的实时区域(role="status")用于播报与控件无关的非紧急更新,例如 Toast 和结果数量。role="alert" 仅用于播报与控件无关的紧急错误。
重复播报的礼貌消息需要一个稳定的空区域,并在文本更新前渲染该区域。动态插入的警报在不同环境中的支持情况不一,因此请在目标读屏软件上进行测试。参见 screen-readers.md。
根据用途编写替代文本
装饰性图片使用 alt=""。信息性图片描述其含义。功能性图片描述其操作,而不是图片本身。完整表格见 screen-readers.md。
结构就是导航
使用能够描述各自内容区域并组成连贯大纲的标题。提供一个可见的主要 <main> 地标。如果重复导航或界面元素位于其前方,则将“跳转到内容”链接设为第一个可聚焦元素。带锚点的标题应设置 scroll-margin-block-start。
适应缩放和文本调整
文本必须能承受 200% 的缩放(1.4.4),页面也必须能在 320px 宽度下重排,且无需水平滚动(1.4.10)。文本容器使用 min-height,而非 height;其余修复由 better-layout 负责。切勿在视口 meta 中设置 maximum-scale=1 或 user-scalable=no。iOS 输入框缩放问题则通过 better-typography 的 16px 规则修复。
完成前检查
| 模式 | 修复方式 |
|---|---|
outline: none 或 outline-none,且附近没有 focus-visible 替代样式 | 恢复浏览器焦点环,或添加经过验证的自定义焦点环 |
<div onClick 或 <span onClick | 使用 <button>;若用于导航,则使用 <a href> |
role="button" 或 role="tab",但没有 onKeyDown | 使用原生元素,或实现 APG 按键映射 |
tabIndex={1} 或任何正数 tabindex | 修正 DOM 顺序,并使用 0 |
提交按钮上设置了 disabled={!isValid} | 保持按钮可用,并在提交时进行验证 |
{msg && <div role="status">,区域连同其文本一起挂载 | 先渲染空区域,再更新其中的文本 |
成功提示上设置了 aria-live="assertive" | 使用 role="status" |
<img 没有 alt 属性 | 若为装饰性图片,使用 alt="";否则描述其用途 |
aria-label 文本没有包含可见标签 | 以可见文本作为名称的开头 |
按钮、链接或输入框的祖先元素上设置了 aria-hidden | 移除它,或让该子树变为 inert |
maximum-scale=1 或 user-scalable=no | 移除 |
原生 disabled 控件上有工具提示 | 将文本放在控件旁,或使用 aria-disabled 使控件仍可聚焦 |
使用了 onDragStart 或拖拽库,但没有按钮替代方案 | 添加单指针操作路径,以实现相同结果 |
报告
严重级别。 HIGH 表示阻碍任务完成、使辅助技术无法获取内容,或造成系统性故障。MEDIUM 表示显著增加交互难度。LOW 表示局部细节问题。此领域的问题一旦发现,就属于 better-interface 的 HIGH 升级触发条件:缺少可访问名称、缺少焦点指示器,或只有指针操作路径而没有键盘操作路径。忽略减少动态效果设置、在 320px 宽度或 200% 缩放时丢失内容,以及仅通过颜色传达含义,也属于此类问题。
验证。 无需浏览器即可检查:每个交互元素是否都有可访问名称、非原生控件是否有键盘事件处理程序、焦点样式、prefers-reduced-motion 防护,以及表单标签是否绑定到对应输入框。使用浏览器时:按顺序通过 Tab 键遍历操作流程,从无障碍树读取计算出的名称和角色,确认每个焦点停留处都有可见的焦点指示器,并运行自动化审查。将所有无法执行的检查报告为 Not verified。
格式。 按违反的原则对发现的问题分组,并按严重级别排序;每个根本原因占一行,列出该问题出现的所有位置:
| 严重级别 | 位置 | 修复前 | 修复后 | 原因 |
|---|
Location 使用 path/to/file:line 格式。Why 说明相关的 WCAG 准则或原则以及对用户的影响。
若仍有任何 HIGH 问题,以 Block 结尾;否则以 Approve 结尾,并将其余待办事项保留在表格中。未检查的覆盖范围绝不标记为 Approve。若没有可报告的问题,请写明“No actionable accessibility findings”,并报告验证情况。