关于 keyboard
keyboard 是一项仅用键盘检查运行中页面的技能。它按顺序记录焦点停靠点,并报告无法到达、看见或操作的控件。
主要功能
- 01使用 Tab 和 Shift+Tab 遍历页面
- 02记录并编号焦点停靠点
- 03检查控件的键盘可达性与操作
- 04测试覆盖层及内容移除后的焦点
- 05按停靠点和按键报告问题
适用场景
- 01审查网页的键盘可访问性
- 02检查菜单和对话框的键盘行为
- 03查找删除内容后的焦点丢失
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ playful-design/ router --skill keyboard安装后在 Claude Code 中输入/keyboard确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEtabstops.jsagents/openai.yaml详细介绍
键盘
这项技能会收起鼠标,只用按键操作正在运行的页面。它会按顺序记录每个焦点停留点,并返回一份编号报告,列出键盘无法到达、查看或操作的内容。
每个停留点都要按键验证,绝不从代码推断
焦点顺序、可达性和操作方式,都要通过在运行中的页面按键来判断。未在遍历中按键验证的停留点一律标记为 Not verified,绝不擅自假定。任何无法到达的控件,不论多不起眼,都是一项发现。
焦点环的显示方式、对话框焦点陷阱和可访问名称属于 defaults,相关故障需引用其 id。打开运行结果属于 verify。强制打开隐藏状态属于 lab。
1. 加载记录器
打开用户指定状态下的页面,不要点击任何内容。通过浏览器的 evaluate 调用运行 tabstops.js。它会先返回无法通过键盘到达的指针目标,然后随着按键操作记录每个停留点。根据标记语言判断顺序或可达性属于 keyboard-press-the-keys。
通过受信任的输入方式发送按键,例如 Playwright 的 keyboard.press 或操作系统。派发 DOM KeyboardEvent 不会移动焦点,因此,如果遍历没有任何停留点,就说明按键根本没有送达。
2. 先向前遍历,再向后返回
从页面顶部按 Tab,直到焦点离开页面,然后按 Shift+Tab 回到起点。读取 window.__keyboard.stops 并调用 window.__keyboard.highlight()。
停留点应遵循布局的阅读顺序。从页眉跳到页脚再返回,或任何正数 tabindex,都属于 keyboard-order-follows-layout。
每个停留点都会在屏幕上显示指示标记。没有可见焦点环的停留点属于 keyboard-see-every-stop。焦点落在已关闭抽屉中的链接上属于 keyboard-no-hidden-stops。没有名称的停留点需引用 defaults-name-icon-buttons。
当导航位于主要内容之前时,第一个停留点应是指向主要内容的跳过链接。在第一个结果之前有二十个页眉停留点属于 keyboard-skip-link。
3. 到达每个控件
将停留点与页面显示的内容以及记录器的 unreachable 列表进行对照。遍历时焦点从未落在其上的可点击 div 属于 keyboard-reach-every-control。
4. 操作每个控件
Enter 和 Space 用于按下按钮,Enter 用于打开链接,Space 用于切换复选框和开关。能够响应点击但无法通过按键操作的控件属于 keyboard-operate-every-control。
菜单、标签页、单选按钮组、列表框和网格只占用一个 Tab 停留点,内部通过方向键移动。菜单中每个项目都各自占用一个 Tab 停留点,属于 keyboard-arrows-inside-composites。
Escape 用于关闭已打开的菜单、弹出框、侧边面板或对话框。只能通过点击关闭的覆盖层属于 keyboard-escape-closes。
5. 打开并关闭每个覆盖层
通过键盘打开每个对话框、菜单和弹出框。焦点会移入其中,在模态框内保持,并在关闭时返回触发控件。此处故障需引用 defaults-trap-and-return-focus。
6. 移除内容,然后查找焦点
通过键盘删除一行、关闭提示消息、折叠某个分区并提交表单。焦点应落在相邻项、容器或结果上。若记录器将某个停留点标记为 lost,且焦点留在 body 上,则属于 keyboard-focus-survives-removal。
7. 报告遍历结果
将停留点按编号列出,并写明角色和名称,同时提供显示 highlight() 编号的截图。每项发现都要注明对应的停留点编号和失效的按键。没有停留点编号和失效按键的发现属于 keyboard-numbered-walk。
这组对照
每项检查都是一组对照。问题行旁边就是替代它的行。
| 规则 | 问题项 | 替代项 |
|---|---|---|
keyboard-press-the-keys | “标记使用了按钮,因此可以通过键盘访问” | 使用 Tab 和 Shift+Tab 记录的键盘操作过程 |
keyboard-order-follows-layout | 搜索字段上设置了 tabindex="3" | 不设置正数 tabindex,并将字段放在阅读顺序中 |
keyboard-see-every-stop | 第 7 个停靠点获得焦点时没有可见的焦点环 | 第 7 个停靠点显示项目的 :focus-visible 轮廓 |
keyboard-no-hidden-stops | 抽屉关闭时,Tab 落在其中的链接上 | 抽屉关闭时为其设置 inert |
keyboard-skip-link | 到达第一个结果前要经过 20 个页眉停靠点 | 将 Skip to Content 链接设为第 1 个停靠点 |
keyboard-reach-every-control | <div onClick={openRow}> | <button onClick={openRow}> |
keyboard-operate-every-control | 一个只能通过点击切换的开关 | 按 Space 键即可切换 |
keyboard-arrows-inside-composites | 一个菜单内有 8 个 Tab 停靠点 | 只有 1 个停靠点,使用方向键在各项之间移动 |
keyboard-escape-closes | 一个只能通过点击外部关闭的弹出层 | 按 Escape 键可关闭,并将焦点返回触发器 |
keyboard-focus-survives-removal | 删除行后焦点落在 body 上 | 焦点落在下一行上 |
keyboard-numbered-walk | “键盘支持参差不齐” | “第 12 个停靠点:在 Notifications 上按 Space 键没有效果” |
报告
严重性。 HIGH 表示键盘无法到达或操作某个控件,或某个操作后焦点丢失并落在 body 上。MEDIUM 表示某个停靠点不符合阅读顺序、没有可见的焦点环,或隐藏在屏幕外;也包括组合控件中每项都占用一个 Tab 停靠点,或覆盖层无法通过 Escape 关闭。LOW 表示缺少跳过链接,或报告中的停靠点未编号。
格式。 每个根本原因列出一条发现,编号并注明停靠点:
1. file:line - [rule-id] stop N, key, what is wrong
如果未找到源代码行,请引用记录器记录的元素。随后提供 Rule | Count | Severity 汇总。只要还有任何 HIGH 项,就标记为 Block;否则标记为 Approve。将跨源框架中的内容标记为 Not verified。