应以 Lighthouse Accessibility 分数为基线,重点监控“自动修复项”变化率;其审计不执行 JS,仅扫描静态 HTML,分数变动直接反映 img alt、label/input 关联、nav 包裹、标题层级等硬伤修复效果。

用 Lighthouse 的 Accessibility 分数做 baseline 对比
别只看总分,重点盯住“自动修复项”的变化率。Lighthouse 的 Accessibility 审计不执行 JS,只扫描静态 HTML,所以分数变动直接反映你改了哪些硬伤:img 补了 alt、label 和 input 的 for/id 对上了、nav 包住了链接、标题没跳级——这些都会在下一轮跑分时立刻体现。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 每次重构前,在相同设备(选
Mobile)、相同页面路径、相同网络条件下跑一次 Lighthouse,保存 JSON 报告;重构后重跑,用 diff 工具比对categories.accessibility.score和具体 audit 结果(如image-alt、label、heading-levels) - 如果
color-contrast项持续报错,说明问题不在 HTML 层,而是 CSS 写死颜色或对比度计算被工具误判,需单独用 axe DevTools 或 Contrast Checker 验证 - 分数涨了但
aria-*类 audit 没变,大概率是你没动交互层——比如仍用div onclick而非button,或没加tabindex="0"
axe DevTools 定位到行级违规元素
Lighthouse 给的是面,axe 给的是点。它能直接标出 DOM 树中哪个 div 缺少 role="button"、哪行 table 没配 scope、哪个 fieldset 漏了 legend——这对验证“是否真改到位”至关重要。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 在 Chrome DevTools 中打开 axe DevTools 面板,勾选 “Include automated checks only”,避免人工判断项干扰;点击 “Analyze” 后,展开每条 issue,看 “Target” 字段指向的具体元素和位置(如
#main > div:nth-child(2) > div) - 对批量替换的语义标签(如把
div.header替成header),用document.querySelectorAll('div.header')确认是否清零;再查document.querySelectorAll('header:not([class*="navbar"])')看是否误伤了不该动的区域 - 注意 axe 的 false negative:它不检测键盘焦点顺序是否合理、
aria-live区域更新是否过频——这些得靠人工 tab 测试
CI 中拦截新增可访问性缺陷
单次整改有效不等于长期可靠。只要 PR 里混进一个没 alt 的 img,或者新写的 section 没配标题,质量就倒退。必须让机器卡在提交前。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 在 CI 脚本里加
npx axe-core --reporter=cli src/**/*.html,配合--rules指定关键项(如image-alt,label,heading-order),失败即阻断合并 - Git pre-commit hook 里跑
html-validate --config .htmlvalidate.json,配置"semantic-elements": "error"和"attr-accesskey": "warn",本地就能拦住低级错误 - 对历史遗留 class(如
btn-primary)建白名单,但禁止新增;新 class 必须走 BEM 规范,否则 lint 直接报错——否则重构后很快又冒出一堆div.card-body
用 Storybook 截图比对捕捉结构意外变动
语义标签改完,视觉可能不变,但 DOM 结构已不同。比如把 div.main 换成 main,样式没崩,但屏幕阅读器播报逻辑变了。Storybook 的视觉回归不是比像素,而是比结构快照。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 每个重构后的组件存为 Storybook story,开启
play函数注入 axe 扫描逻辑,自动生成无障碍报告并附在 story 页底部 - 用
chromatic或percy做 DOM 快照比对,关注role、aria-属性增减、语义标签变更(如div→nav)、tabindex出现与否 - 截图比对发现
main标签多嵌套了一层?说明某个模板片段被重复 include —— 这类问题 Lighthouse 和 axe 都不会报,但会破坏main的唯一性约束
div 换成 header,而是确保每次新增的 section 都带 h2,每个 img 的 alt 都非空且有意义,所有动态内容更新都通过 aria-live 可读——这些细节不在工具报告第一屏,得靠流程兜底。



















