<p>vscode-html-validate 能检测 aria-* 和 role 的静态误用,如 role="button" 缺 tabindex 或事件;axe-core CLI 在运行时检查焦点、对比度等;脚本可自动补 alt 和 button type,但语义判断需人工;HTML Washer 会误删关键语义属性,不可用于生产。</p>

用 vscode-html-validate 检查 aria-* 和 role 的误用
很多“看似可访问”的代码实际违反 WCAG,比如 role="button" 套在 <div> 上却没加 tabindex="0" 或 onclick 事件监听,屏幕阅读器会识别为按钮但无法触发。vscode-html-validate 能捕获这类模式,前提是配置启用 aria-allowed-attr、aria-required-attr 和 aria-valid-attr-value 规则。在 VS Code 的 settings.json 中加入:
"html-validate.options": {
"rules": {
"aria-allowed-attr": "error",
"aria-required-attr": "error",
"aria-valid-attr-value": "error",
"no-inline-style": "warn"
}
}注意:它不会检查 JS 动态设置的 aria- 属性,只校验静态 HTML;若项目用模板引擎(如 Handlebars),需确保插件能解析后缀为 .hbs 或 .html 的文件。
用 axe-core CLI 在构建前跑可访问性快照
vscode-html-validate 是静态检查,axe-core CLI 才能模拟真实渲染环境,检测焦点顺序、颜色对比度、alt 缺失等运行时问题。执行前需本地起服务(如 npx serve -s dist),再运行:
npx axe-core http://localhost:5000 --tags=wcag2a,wcag2aa --output=accessibility-report.json
常见陷阱:
立即学习“前端免费学习笔记(深入)”;
-
http://localhost:5000必须是完整 URL,不能写./index.html—— axe 需要 HTTP 环境才能加载 JS 和计算样式 - 报告默认只输出失败项,加
--verbose才能看到所有检查项状态 - 若页面依赖登录态,得先手动登录并传入 cookie(
--cookie "session=xxx"),否则大量区域被判定为“不可访问”
批量修复 img 缺失 alt 和 button 缺失 type
人工补 alt 效率低还易漏,可用 Node.js 脚本自动打桩 + 标记待人工审核:
const fs = require('fs');
const html = fs.readFileSync('index.html', 'utf8');
const patched = html
.replace(/<img([^>]*?)\/>/g, (m, attrs) => {
if (!/alt=["']/.test(attrs)) {
return m.replace(/>$/, ` alt="[TODO: describe image]">`);
}
return m;
})
.replace(/<button([^>]*?)>/g, (m, attrs) => {
if (!/type=["']/.test(attrs)) {
return m.replace(/<button/, '<button type="button"');
}
return m;
});
fs.writeFileSync('index.patched.html', patched);关键点:
- 正则中用
[^>]*?避免跨标签匹配,比.*?更安全 -
alt="[TODO: describe image]"是显式标记,CI 流程可 grep 出来阻断上线 - 不自动填空描述,因为语义必须由人判断;同理,不给
<a href="#">加role="button"—— 这属于逻辑重构,脚本不该越界
为什么不能只靠 HTML Washer 或在线工具做可访问性清洗
HTML Washer 会无差别剥离所有 class、id、aria- 属性,结果可能把 aria-live="polite" 或 id="main-content" 也删了,反而降低可访问性。它适合“克隆布局”场景,不适合生产环境清洗。真正有效的自动化清洗,必须:
- 保留所有语义化属性(
alt、lang、required、aria-) - 只修正已知反模式(如无
type的<button>、无href的<a>) - 对不确定项打标而非删除(如空
alt=""可能合法,但alt="image"必须改)
最常被忽略的是:可访问性不是“有没有”,而是“用得对不对”。一个 role="navigation" 如果包裹了广告位,比没有更糟糕。



















