是 html5 规定的唯一语义化主内容容器,每页仅允许一个,不可嵌套于 等结构元素内,替代 div+role="main" 更规范、更利于可访问性与 seo。

main 元素是语义化定义主要内容的唯一标准方式
HTML5 明确规定 <main></main> 是文档中「对当前文档或应用最具代表性内容」的容器,且每个页面最多只能有一个(除非用 hidden 属性临时隐藏)。它不是样式标签,不带默认样式,但对可访问性(如屏幕阅读器跳转)、SEO 和语义结构至关重要。
常见错误现象:role="main" 被滥用在 <div> 上;多个 <code><main></main> 出现在同一页面;把导航、页脚、侧边栏塞进 <main></main> 里。
- 只包裹真正“核心内容”:比如文章正文、产品列表、表单主体,不包括页眉、面包屑、相关推荐栏
- 不能嵌套在
<article></article>、<aside></aside>、<footer></footer>、<header></header>、<nav></nav>内部 - 若页面有多个视图(如 SPA 的路由切换),每次激活新视图时,应确保仅一个
<main></main>为 visible 状态,其余加hidden
为什么不用 div + role="main" 替代 main 元素
虽然 <div role="main"> 在可访问性上能被识别,但它绕过了 HTML5 语义约束机制,容易引发隐性问题。
<p>使用场景:老项目升级时未迁移到 HTML5 doctype,或需兼容极旧浏览器(IE8 及以下)——但这类场景现在极少,且可用 polyfill 补救。</p>
<p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p>
<ul>
<li>
<code><main></main> 自带隐式 ARIA role,无需手动写 role="main";重复写反而可能触发校验警告
<main></main> 有原生快捷键支持(如 JAWS 的 M 键跳转),而 role="main" 依赖 JS 注入或额外声明,稳定性差The element main must not appear as a descendant of the header element 这类提示在 <div role="main"> 下完全不会出现,掩盖结构缺陷
<h3>main 元素与 aria-main 的关系和冲突点</h3>
<p><code>aria-main 是 ARIA 1.1 引入的属性,用于在无法使用 <main></main> 时标记主区域。但它和 <main></main> 同时存在时,以 <main></main> 为准,aria-main 会被忽略。
性能 / 兼容性影响:无运行时开销,但混淆使用会降低代码可维护性。
- 不要这样写:
<main aria-main="true"></main>——aria-main在<main></main>上无效且冗余 - 也不该这样写:
<div aria-main="main"> —— 正确值是 <code>aria-main="true",且仅当没有<main></main>时才考虑 - 若用 Web Components 或 Shadow DOM,外部
<main></main>无法穿透到影子树内,此时可在影子根节点用aria-main="true"做补充 - 在根布局组件中统一放置一个
<main></main>,子组件只负责填充内容,不自建<main></main> - Next.js 中,
app/目录下每个路由段默认渲染为独立页面,<main></main>应放在layout.tsx中,而非每个page.tsx - Vue Router 的
<router-view></router-view>外层必须包一层<main></main>,且禁止在<router-view></router-view>内部再出现<main></main>
主流框架中如何安全使用 main 元素
React、Vue、Svelte 等现代框架本身不限制 <main></main>,但组件拆分和条件渲染容易导致多个 <main></main> 被同时挂载(比如路由组件各自包含 <main></main>)。
错误现象:Lighthouse 报告「Document has more than one main landmark」;屏幕阅读器连续触发两次主区域跳转。
最常被忽略的是动态内容加载后的语义更新:比如点击「加载更多」后追加内容,如果新内容改变了主区域边界(例如从列表页进入详情页),必须同步调整 <main></main> 的位置或 visibility 状态,否则辅助技术会持续聚焦在旧区块。











