EP12. "wp-accessibility-review 无障碍审查"
🔒 登录后可标记已读- 你的自定义 dropdown 菜单是不是只能用鼠标点开、按 Tab 键完全碰不到?这种问题肉眼看不出来,但对用键盘操作的用户来说整个功能等于不存在
wp-accessibility-review是jorgerosal/wordpress-skills这套 18 个 skill 里专门审查 WordPress 无障碍实现的一个,覆盖语义化标签、键盘操作、焦点管理、表单标签、错误提示这几块- 核心原则一句话:无障碍应该写进结构、交互、状态变化里,不是事后用几个零散的 ARIA 属性补丁贴上去
- 前置知识:先看过 EP10「wp-admin-ui-development 后台界面审查」,两者都会碰到后台表单/交互组件,这个 skill 补的是无障碍这一层
重点内容
这个 Skill 是做什么的
wp-accessibility-review 系统化审查 WordPress 主题模板、block 输出、插件后台界面里的无障碍实现,覆盖语义化标签、键盘行为、焦点可见性与焦点归位、状态变化的提示方式、modal/menu/accordion/tab 这类交互组件的语义。
适合用在:
- 审查主题模板或 block 输出的标签结构
- 审计后台表单或自定义插件 UI
- 检查 modal、tab、accordion、menu 这类交互组件
- 审查表单标签、错误提示、焦点行为
- 发布前验证无障碍实现是否到位
不适合用在:
- 没有实现上下文、纯视觉设计层面的评论
- 纯性能审查或纯安全审查
- 只凭截图判断色彩对比度
触发方式
| 方式 | 写法 | 说明 |
|---|---|---|
| 斜线指令(完整版) | /wp-a11y-review [path] | 完整审查,结果按文件、按严重度分组 |
| 斜线指令(快速版) | /wp-a11y [path] | 只抓高风险问题,速度快 |
| 自然语言 | 「检查这个 modal 的无障碍」「is this accordion keyboard accessible」 | Claude 判断意图符合就自动触发 |
审查流程
- 识别检查对象:前端模板、block 输出、后台界面、交互式 JS 组件
- 检查结构语义:标题层级顺序、按钮 vs 链接用对了没有、表单 label 关联、表格/列表语义
- 检查交互行为:键盘能不能操作、焦点是否可见并正确归位、需要时有没有 live region 或状态提示、dialog/accordion/tab 的语义是否正确
- 按严重度分类:CRITICAL 是核心操作键盘碰不到、必填表单控件没有 label、modal/menu 焦点处理错误(困住或漏掉);WARNING 是语义薄弱、错误提示跟表单没关联、ARIA 用错、可点击元素不是真正的按钮;INFO 是标题结构、帮助文字、landmark 用法可以再优化
按检查对象分类的坑
| 检查对象 | CRITICAL | WARNING | INFO |
|---|---|---|---|
| 模板与标签结构 | 交互元素用 div/span 实现,没有键盘支持 | 标题结构或 landmark 缺失;表单输入没有 label | 能用原生元素就不要堆 ARIA |
| JavaScript 交互 | 打开 modal 时焦点没移进去、关闭时没归位 | 键盘处理不完整;状态变化只体现在视觉上 | 异步更新可以用 live region 提示 |
| Block 与后台 UI | — | Inspector controls 或 block UI 标签不清楚;后台通知没有恰当播报 | 空状态提示、辅助文字可以更清楚 |
交互组件的具体检查点
modal/menu/accordion/tab 这类组件官方文档专门列了一份检查清单:
- 所有控件都能用键盘操作
- overlay 出现/关闭时焦点管理是否正确(打开时焦点移进去,关闭时焦点归位到触发它的元素)
- 展开/收起状态有没有用无障碍方式表达出来,不是只靠视觉变化
- 已知的常见失败模式:Escape 键没反应、Tab 键能移动到 modal 背后的内容、隐藏内容依然能被键盘 focus 到
快速扫描指令(rg)
# CRITICAL:非语义元素上挂点击/键盘事件、表单控件、dialog/modal 实现
rg -n "<(div|span)[^>]+on(click|key)" . -g '*.{php,html,js,jsx}'
rg -n "<input|<select|<textarea" . -g '*.{php,html}'
rg -n "dialog|modal|aria-modal|role=['\"]dialog" . -g '*.{php,html,js,jsx}'
# WARNING:ARIA 用法需要人工核对、按钮/链接语义、焦点管理代码
rg -n "aria-|role=" . -g '*.{php,html,js,jsx}'
rg -n "<a[^>]+href=['\"]#|<button[^>]+onclick" . -g '*.{php,html}'
rg -n "focus\(|tabindex|keydown|keyup" . -g '*.{js,jsx,php}'
# INFO:标题层级与 landmark 结构
rg -n "<h[1-6]|<main|<nav|<aside|<header|<footer" . -g '*.{php,html}'
实操示例
// ❌ CRITICAL:用 div 实现按钮,键盘完全操作不到
<div class="toggle-menu" onclick="toggleMenu()">菜单</div>
// ✅ GOOD:用原生 button,键盘、屏幕阅读器都能识别
<button type="button" class="toggle-menu" onclick="toggleMenu()" aria-expanded="false">
菜单
</button>
// ❌ CRITICAL:表单输入没有关联的 label
<input type="text" name="email" placeholder="邮箱">
// ✅ GOOD:label 用 for 关联到 input 的 id,placeholder 不能替代 label
<label for="myplugin-email">邮箱</label>
<input type="text" id="myplugin-email" name="email">
// ❌ CRITICAL:modal 打开时焦点没移进去,关闭时也没归位
function openModal() {
document.getElementById('my-modal').classList.add('is-open');
}
// ✅ GOOD:打开时把焦点移进 modal,关闭时归位回触发它的元素
let triggerElement;
function openModal( trigger ) {
triggerElement = trigger;
const modal = document.getElementById( 'my-modal' );
modal.classList.add( 'is-open' );
modal.querySelector( '[data-autofocus]' ).focus();
}
function closeModal() {
document.getElementById( 'my-modal' ).classList.remove( 'is-open' );
if ( triggerElement ) {
triggerElement.focus();
}
}
怎么安装
这个 skill 是 wordpress-skills 这个开源仓库(jorgerosal/wordpress-skills)打包的 18 个技能之一,安装一次,18 个技能一起到位,不用逐个装:
Claude Code:
| 方式 | 指令 | 适用场景 |
|---|---|---|
| 装进单个项目(推荐) | git submodule add https://github.com/jorgerosal/wordpress-skills.git .claude/plugins/wordpress-skills | 只想在这个项目用,团队成员 clone 项目就一起有 |
| 装到自己账号 | git clone https://github.com/jorgerosal/wordpress-skills.git ~/.claude/plugins/wordpress-skills | 所有项目都能用 |
| 只装这一个 skill | cp -r claude-skills/wp-accessibility-review ~/.claude/skills/ | 只想要无障碍审查这一个功能,不要其他 17 个 |
装完重启 Claude Code,进到一个 WordPress 项目里跑 /wordpress-skills:wp-a11y-review 验证有没有装成功(用 marketplace/submodule 方式装的话,指令前面会带插件命名空间 wordpress-skills:;用「只装这一个 skill」的方式则不带命名空间,直接 /wp-a11y-review)。
Claude Desktop / claude.ai: 走 Settings → Capabilities → Skills,上传技能文件夹(把 claude-skills/wp-accessibility-review 这个文件夹打包上传,里面要包含 SKILL.md)——跟 Claude Code 的 git submodule/marketplace 安装方式不同,Desktop 端是手动上传 UI,装好之后同样能用自然语言或 slash 指令触发。
常见错误
- ❌ 只凭截图判断色彩对比度不够就报无障碍问题——skill 明确说明这类纯视觉层面、脱离实现上下文的判断不在它的范围内,色彩对比度需要专门工具而不是代码审查
- ❌ 看到元素上有
aria-*属性就默认它用对了——ARIA 用法官方只列为「需要人工核对」的 WARNING 信号,不是出现就代表实现正确,也不是没有就代表有问题 - ❌ 把「可点击的
<a href="#">」和「用onclick的<button>」都当成同一类问题——前者是链接语义被滥用成按钮,后者本身用对了元素,只是可能缺type="button",两者严重度和修法不一样 - ❌ 只检查 modal 打开时的焦点,没检查关闭时焦点有没有归位——官方检测点明确要求「打开移入、关闭归位」两段都要看,只做一半等于没做完
- 💡 「视觉上有变化」不等于「无障碍上有变化」——展开/收起、选中/未选中这类状态,光靠颜色或图标切换,屏幕阅读器用户完全感知不到,必须配合
aria-expanded/aria-selected这类属性或 live region
Sources
官方文档:
- wordpress-skills(GitHub 仓库)— https://github.com/jorgerosal/wordpress-skills
- wp-accessibility-review SKILL.md — https://github.com/jorgerosal/wordpress-skills/blob/main/claude-skills/wp-accessibility-review/SKILL.md