<main>不能嵌套在<section>内,因其是页面唯一主内容容器,W3C明确禁止被<section>等语义标签包裹;错误写法破坏语义,导致屏幕阅读器跳过导航、SEO降权。

main不能嵌套在section里,header不一定要写在页面最上面,ol做目录时a必须直接包文本——这些不是“可选规范”,而是浏览器解析、辅助技术识别和SEO抓取的实际执行依据。不按逻辑嵌套,代码照样能渲染,但结构会失效。
为什么main不能放在section内部
W3C 明确规定main必须是文档级流内容容器,且只能有一个(除非hidden)。它不能作为任何“分区根元素”(如section、article、nav)的子元素。
- 错误写法:
<section><main>...</main></section>—— 屏幕阅读器可能跳过该main,或把它当作普通区块播报 - 正确结构:
main应为body的直接子元素之一,和其他语义容器(如header、nav)并列 - 验证方式:Chrome DevTools → Elements 面板 → 右键
main→ “What’s this element?” → 检查是否被标记为role="main",且不在任何 sectioning root 内部
header和footer的作用域靠“最近节根”决定
header不会因为写在页面顶部就自动属于整页;它绑定的是离它最近的“节上下文”,比如body、section或article。
- 常见误用:
<body><header>网站标题</header><section><header>文章标题</header></section></body>—— 第二个header属于section,第一个属于body,两者互不干扰 - IE 兼容注意:
header在 IE 中无语义,纯属div,别指望它提升无障碍或 SEO - 判断方法:Elements 面板中右键
header→ “What’s this element?” → 看它是否列在 “Sectioning content” 下;若没有,则它未被识别为节内 header
目录必须用ol,且a必须直接包裹文本
目录本质是有序导航路径,ol提供原生顺序语义、屏幕阅读器编号播报、start/type等可控属性;ul只是视觉模拟,无结构含义。
立即学习“前端免费学习笔记(深入)”;
- 错误写法:
<li><a href="#ch2"><span>第二章:DOM 操作</span></a></li>——span阻断了焦点与文本的关联,键盘用户无法聚焦,AT 无法把链接和标题语义绑定 - 正确写法:
<li><a href="#ch2">第二章:DOM 操作</a></li>——a直接包含可读文本 - 锚点 ID 必须唯一且大小写敏感,
<h2 id="ch2">和<a href="#ch2">必须完全一致 - 多级嵌套时,子
ol必须完整写在父li内,缩进对齐层级,否则闭合错位会导致大纲断裂
浏览器大纲生成只认 heading + sectioning root,不认 class 或 CSS
文档大纲由浏览器根据h1–h6顺序和最近的section、article等节根自动构建,CSS 样式或class名完全不影响这个过程。
- 跳级写 heading(如
h2后直接h4)不会报错,但大纲会推断出错误层级,导致屏幕阅读器导航错乱 - 空
section(没含 heading)仍出现在大纲中,显示为“无标题”,对可访问性不利 - 用
div class="title"替代h2,等于从大纲中彻底删除该节点 —— 即使样式再像标题,机器也看不到它 - 过度嵌套
section(三层以上)会让大纲树过深,辅助技术用户需多次按键才能退出一个区块
真正卡住人的从来不是标签怎么写,而是“这个标签在 DOM 树里归谁管”“它在大纲里算第几层”“AT 会怎么读它”。这些逻辑不显式报错,但一上线就被读屏软件暴露、被搜索引擎降权、被审计工具标红。看 HTML 结构,得盯着嵌套关系,而不是标签名字。



















