每页必须且只能有一个<main>元素,且不可嵌套在<header>、<footer>、<aside>或另一个<main>内;<main>应包含独立可分发的内容,多主体场景须用<article>替代。

为什么必须唯一且不能嵌套
浏览器和辅助技术会把多个 <main></main> 当作结构错误处理:屏幕阅读器跳过第二个起的所有 <main></main>,Googlebot 降低整页 SEO 权重,axe 工具直接报 document-has-one-main 错误。
常见错误现象包括:页面底部的“相关文章”区块被包进另一个 <main></main>;组件库渲染时重复插入 <main></main>;SSR 模板中条件渲染导致意外嵌套。
- 每页只允许一个
<main></main>,且不能在<header></header>、<footer></footer>、<nav></nav>或另一个<main></main>内部 -
<main></main>应包含独立、可分发的内容(如一篇博文、一条新闻),可自带<header></header>和<footer></footer> - 若需多个“主体内容”(如仪表盘多卡片),用
<section></section>+<h2></h2>替代,而非拆成多个<main></main>
如何选对 <section></section> 和 <article></article>
错用比不用更危险:<section></section> 被当成“视觉分隔”,<article></article> 被当“样式容器”,结果是 axe 报 region 缺失、SEO 权重稀释、JS 查询失效。
使用场景很明确:<article></article> 表示自包含、可独立分发的内容(博客、新闻、商品卡片);<section></section> 是主题明确、与主内容相关但非独立的区块(作者简介、评论区、侧边推荐)。
立即学习“前端免费学习笔记(深入)”;
-
<section></section>必须配<h2></h2>~<h6></h6>,否则部分读屏软件忽略,CSS 选择器如main section h2也容易误匹配 -
<article></article>可嵌套在<section></section>或<main></main>中,但不要用它包裹导航栏或页脚 - 两个连续
<section></section>主题一致?合并为一个,用<h3></h3>做子标题,避免 DOM 层级膨胀
用 data-module 替代 class 做 JS 锚点
靠 class="header" 查 DOM,本质是把语义逻辑耦合进样式层——设计师删 class、CSS 覆盖、组件复用时 class 冲突,都会让 document.querySelector('.header') 失效。
data-module 是专为模块标识设计的属性,不影响样式、不被 CSS 无意修改、支持版本管理,且天然规避 id 重复问题。
- 每个功能模块根元素加
data-module="header"、data-module="product-list" - 配合
data-version="1.3",CI 流程可校验 HTML 片段是否匹配文档规范 - JS 统一查
document.querySelectorAll('[data-module="header"]'),稳定可靠 - 禁止用
id做模块锚点——循环渲染商品卡片时,id="product-item"必然重复,document.getElementById()只返回第一个
嵌套超过三层就该重构
DOM 树过深不只是影响性能,更是维护灾难:div > div > div > article > h2 这种结构,改个样式得写四层选择器,删中间一层 div 就可能让 JS 绑定失效、CSS 规则失效、甚至触发无障碍树重建。
现代布局(Flexbox/Grid)已支持扁平结构,没必要靠嵌套“撑开空间”或“模拟容器”。
- 理想嵌套控制在 3 层内:例如
body > main > article或body > section > article - 检查冗余包裹:Chrome DevTools → Elements → 右键节点 → “Break on” → “Attribute modifications” 可暴露动态插入的无意义
div - DOM 子元素超 50 个时,重排压力明显上升,长列表建议用
<section></section>分块,而非堆在一个容器里
<section></section> 缺了 <h2></h2> 导致 axe 报错却没人定位到源头,或是 data-module 拼写漏了个横线让整块 JS 失效。这些点不显眼,但每次交接、每次上线前检查,都得花时间来回确认。



















