lighthouse的accessibility评分不能等同语义结构合规,因其不检查唯一性、标题缺失、位置等核心结构问题,仅报告可见缺陷;需勾选全部四类并配置断言(如landmark-no-duplicate-main)才能全面检测。

为什么Lighthouse的“Accessibility”评分不能直接等同于语义结构合规
Lighthouse 的 Accessibility 分类确实会检查 <h1></h1> 是否缺失、标题是否跳级、<img> 是否缺 alt,但它**不验证 <main></main> 是否唯一、<section></section> 是否带标题、<nav></nav> 是否在 <main></main> 之前**——这些才是语义结构的核心扣分点。工具只报它“能看见”的问题,而 HTML 结构层级错位(比如 <main></main> 套在 <div> 里、<code><section></section> 没配 <h2></h2>)往往被跳过。
常见错误现象:
– 页面跑出 92 分的 Accessibility,但 Lighthouse 的“结构化数据”项却标红“Multiple <main></main> elements found”
– <header></header> 里塞了两个 <h1></h1>,Lighthouse 不报,但 axe DevTools 和 W3C Validator 都会明确提示
- 真正影响语义结构评分的是 Lighthouse 的
SEO和Best Practices分类里的子项,比如 “Document doesn’t have a<main></main>element” 或 “<h1></h1>is not the first heading” - 必须勾选全部四个类别(Performance / Accessibility / Best Practices / SEO)才能触发结构类检查,单选
Accessibility会漏掉关键项 - 本地跑分时若用
lhci autorun,默认 assert 不含结构断言,需手动加"document-has-main-element": ["error"]这类规则
如何用Lighthouse快速定位语义结构硬伤
不是所有结构问题都藏在报告末尾的“建议”里;有些是直接写进“诊断”(Diagnostics)面板的红色条目,得主动翻。
重点关注以下几条诊断信息:
– Document does not have a main landmark
– Heading elements are not in a logical order
– Page has no <code><h1></h1> element
– Links do not have a discernible name(常因 <a></a> 里只有图标没文字或 aria-label)
- 打开 Chrome DevTools → Lighthouse → 点击“Options”展开高级设置,务必勾选
Emulate mobile device和Clear storage,否则缓存 DOM 可能掩盖嵌套错误 - 跑完后不要只看总分,直接点开“Diagnostics”折叠面板,Ctrl+F 搜索
main、header、section,比扫“Opportunities”更高效 - 如果页面用了 SSR 或 hydration,确保 Lighthouse 启动时 JS 已执行完毕,否则
<main></main>可能还在<div id="app"> 里没提升出来——可在 collect 阶段加 <code>"waitFor": "document.querySelector('main')"Lighthouse CI 中如何让语义结构问题真正卡住构建
默认
lhci autorun只生成报告,哪怕<main></main>缺失、<h1></h1>错位,CI 依然绿灯放行。必须靠显式断言强制拦截。在
.lighthouserc.json中,至少要声明这些结构断言:{ "ci": { "collect": { "url": ["http://localhost:3000"], "numberOfRuns": 1 }, "assert": { "assertions": { "document-has-main-element": ["error"], "heading-levels": ["error", {"minScore": 1}], "html-has-lang": ["error"], "landmark-one-main": ["error"], "landmark-no-duplicate-main": ["error"] } } } }-
heading-levels是 Lighthouse 内置断言名,检测跳级(如<h2></h2>后直接<h4></h4>),{"minScore": 1}表示必须 100% 合规,小数无效 -
landmark-no-duplicate-main比landmark-one-main更严格:后者只查是否存在一个<main></main>,前者查是否“没有重复”,能捕获 SSR 渲染残留的旧<main></main> - 如果项目用 Vue/React,
collect.waitFor必须设为真实 DOM 条件(如"document.querySelector('main').offsetHeight > 0"),否则断言在空壳 DOM 上运行,永远通过
结构走查中最容易被忽略的三个物理顺序细节
语义标签的书写顺序,比 class 名和 CSS 位置更重要。Lighthouse 不直接报“源码顺序错乱”,但会连带触发
Accessibility项里的 “Focus order is not sequential” 或 “Heading order is not sequential”。-
<nav></nav>必须出现在<main></main>之前——哪怕视觉上它在页脚,HTML 源码也得提前写;用 CSSorder或flex-direction调整位置不算数 -
<section></section>内部第一个元素要是<h2></h2>~<h6></h6>,不能是<p></p>或<div>;空 <code><section></section>直接算语义滥用,axe 会标 “sectionmust have a heading” -
<header></header>和<footer></footer>可以嵌套,但每个<article></article>自带的<header></header>里只能有一个<h2></h2>(内容级),不能混用站点级<h1></h1>;否则 Lighthouse 的seo类别会警告 “Multiple<h1></h1>elements”
结构走查不是找“有没有标签”,而是确认“标签是否在该在的位置、按该有的顺序、承载该有的语义”。一旦 DOM 顺序和逻辑流脱钩,再高的 Lighthouse 分数也救不了可访问性。
-











