必须唯一且不能嵌套,因其是浏览器、搜索引擎和屏幕阅读器识别页面“唯一核心内容”的强制语义锚点;重复或嵌套会致焦点丢失、seo降权及辅助技术跳过正文。

为什么必须用 <main></main> 而不是 <div class="main">
<p>因为 <code><main></main> 是浏览器、搜索引擎和屏幕阅读器唯一能识别的“页面核心内容”标记。用 <div class="main"> 时,所有辅助技术都把它当成普通容器——导航无法跳过广告直达正文,SEO 会把侧边栏链接和文章正文同等加权,甚至 Google Search Console 可能提示“未明确标识主内容”。<code><main></main> 还自带隐式 ARIA role="main",无需手动补。
<main></main> 的硬性约束有哪些
<main></main> 的硬性约束有哪些这些不是建议,是规范强制要求:
- 一个 HTML 文档中只能出现一次
<main></main> - 不能嵌套在
<article></article>、<aside></aside>、<footer></footer>、<header></header>或<nav></nav>内部 - 不能同时包含多个
<main></main>,哪怕用hidden或display: none也不行(DOM 中仍存在) - 如果页面有多个视图(如 SPA 的 tab 切换),每次只让当前活跃区域保留在
<main></main>内,其余移出或销毁
<main></main> 里该放什么,不该放什么
判断标准只有一个:这块内容是否构成用户访问该 URL 的首要目的?
- ✅ 应放:博客正文、商品详情描述、表单主体、搜索结果列表、API 返回的渲染数据
- ❌ 不该放:顶部搜索框(属于
<header></header>)、登录入口(<header></header>或<aside></aside>)、页脚版权(<footer></footer>)、右侧推荐栏(<aside></aside>) - ⚠️ 模糊地带:评论区。若评论可独立分发(如支持 RSS 订阅),用
<article></article>套;若仅依附于当前文章存在,用<section></section>更准确
常见错误与调试方法
遇到语义失效,先查这几个点:
- 运行
document.querySelector('main')—— 返回 null?说明漏写了或拼错为<maine></maine> - 运行
document.querySelectorAll('main').length—— 大于 1?多处误用,尤其注意 CMS 模板循环中重复插入 - 用 Chrome DevTools 的 Accessibility 面板 → “Landmarks” 标签,看是否显示 “Main” 区域及是否唯一
- 打开 NVDA 或 VoiceOver,按
D(跳转到 main)测试是否能一键进入正文,而非卡在导航栏
最易被忽略的是动态渲染场景:React/Vue 组件中用 v-if 或 {showMain && <main>...}</main> 时,若条件初始为 false,<main></main> 节点根本不会生成,导致整页缺失主地标。必须确保至少一个 <main></main> 在首次渲染时就存在于 DOM 中。











