浏览器根据<h1>到<h6>的出现顺序和相对层级自动生成文档大纲,首个<h1>为根节点,后续标题须逐级递进或回退,跳级(如<h2>后接<h4>)会导致大纲断裂;<section>作为sectioning root可重置内部标题层级,使<h2>在其内成为合法顶层,从而修复跳级问题。
浏览器不靠 class 名、视觉大小或 div 嵌套来推导结构,只认 <h1> 到 <h6> 的出现顺序和相对层级。第一个 <h1> 是根节点,后续每个 heading 必须比前一个最多深一级(<h2> → <h3> 合法),或回退任意级(<h3> → <h1> 也合法);但跳级(<h2> → <h4>)会直接导致大纲断裂。
<section> 能修复“跳级”问题<section> 本身不产生大纲条目,但它是一个 sectioning root,会让内部的 heading 重新计层。比如:<h1> 后紧接 <section><h2>,这个 <h2> 就是该区块的顶层标题,其子级用 <h3> 就不再算跳级。
<h1>首页</h1><h3>功能说明</h3> → <h3> 被当作无父级的孤立项,axe 报 heading-order
<h1>首页</h1><section><h2>功能说明</h2><p>…</p></section> → <h2> 成为合法顶层,语义闭环<nav>、<article>、<aside> 同样是 sectioning root,但语义不可混用:把导航栏包进 <section> 不如用 <nav> 直观大纲不是视觉呈现,而是解析树里的逻辑结构。很多看似正常的行为,实际已破坏可访问性基础:
<div class="h2"> 替代 <h2> → 完全不参与大纲,工具检测为“无标题”<h1>(如 Layout 组件硬编码一个,Page 组件再写一个)→ 浏览器终止主大纲构建,后续所有 heading 降级为同级<footer> 或 <aside> 里写了 <h2> → 仍被计入大纲,污染主体结构display: none 或 aria-hidden="true" 隐藏了 <h1> → 工具仍尝试解析,但上下文丢失,heading-level 突变别信肉眼所见,必须用真实解析工具看浏览器到底怎么理解你的 HTML:
立即学习“前端免费学习笔记(深入)”;
heading-level 是否连续、无突变heading-order、document-has-only-one-h1 等错误真正容易被忽略的是:大纲断裂不会让页面“看起来不对”,但会让屏幕阅读器跳过整块内容、SEO 提取不到层级关系、甚至部分浏览器的“文档概览”功能失效——它静默失效,直到有人依赖它时才暴露问题。