html-validate需结合json输出与脚本解析rule字段统计aria-*修复进度,聚焦aria-hidden误用、aria-label缺失、role冗余等具体规则按页面路径聚合;禁用axe得分,改用axe-core api提取critical/serious违规;ci中存储violation节点定位;组件库迭代需绑定无障碍快照与版本;警惕alt无效值、role语义失效等假修复。

怎么用 html-validate 统计 aria-* 修复进度
直接跑 html-validate 不够,必须提取 rule-violation 的分布和趋势。它默认只输出错误总数,但你需要知道:是 aria-hidden 误用少了,还是 aria-label 缺失降了,或是 role 冗余被清理了。
实操建议:
- 加
--output-format=json输出结构化数据,用脚本解析rule字段(如"aria-allowed-attr"、"aria-required-children") - 按页面路径聚合,比如
/product/list页面的aria-invalid违规从 7 条降到 0,比全局平均值更有业务意义 - 避免把
aria-*当开关——aria-hidden="true"加在<button></button>上是硬性错误,但加在装饰性图标上是合理用法,校验器不会区分,得靠人工标注白名单
为什么不能只看 axe 扫描报告里的“无障碍得分”
axe 的 89 分或 92 分只是加权平均值,掩盖了关键缺陷是否真被修复。比如一个页面有 100 个 <img>,其中 95 个补了 alt,剩下 5 个全是核心商品图——得分高,但对视障用户实际体验毫无改善。
实操建议:
- 禁用 axe 的汇总得分,改用
axe-core的run()API 获取原始 violation 数组,过滤出impact: "critical"或impact: "serious"的项单独统计 - 重点关注三类规则:缺失
alt的非装饰图、tabindex乱用(如负值用于非可聚焦元素)、label未绑定的表单控件——这些直接影响键盘导航和语音播报 - CI 中别只存“通过/失败”,要存每个 violation 的
nodes[0].target(如["#search-input"]),方便回溯到具体 DOM 节点和提交人
如何把可访问性指标绑定到组件库版本迭代
大厂不是靠“全站扫描一次”来评估提升,而是把问题打点到具体组件。比如 Button 组件升级后,所有使用它的页面中 role="button" + tabindex="0" 的冗余写法是否消失?
实操建议:
- 在组件文档页(如 Storybook)嵌入
axe.run(),每次构建自动快照该组件的无障碍状态,并关联package.json的 version 字段 - 用
html-validate自定义插件,匹配特定 class 前缀(如.u-button),只校验该类组件生成的 HTML 片段,排除模板引擎注入的干扰 - 发现某次
@mylib/button@2.4.0发布后,aria-disabled误用率上升 300%,立刻锁定 PR 中新增的 disabled 状态逻辑,而不是等 QA 报 bug
最容易被忽略的“假修复”陷阱
静态扫描能捕获 alt 是否存在,但无法判断 alt="图片" 或 alt="icon" 这类无效值是否被当成已修复。同样,role="navigation" 加在 <div> 上,表面合规,实际没配 <code>aria-label,屏幕阅读器仍报“无名导航”。
真正要盯住的,是那些“语法合法但语义失效”的点:比如 <main></main> 唯一性校验通过了,但它包裹了广告位和弹窗;<nav></nav> 里混着客服电话,不是链接集合;<figure></figure> 没配 <figcaption></figcaption>,导致图片上下文丢失。这些没法靠工具自动打分,得靠人工抽检+用户测试闭环验证。











