<main>是HTML5中唯一标识页面当前视图核心内容的语义化标签,必须且只能出现一次,不能嵌套在header/nav/footer/aside内,应直接作为body子元素,用于包裹随URL变化、不可复用的主体内容。

<main></main> 是 HTML5 中唯一标识页面「当前视图核心内容」的语义化标签,不是视觉容器,也不提供默认样式——它只向浏览器、屏幕阅读器和搜索引擎明确传递“这部分内容是本页独一无二、不可复用的主体”这一信息。用错位置、重复出现或嵌套在语义区块内,会直接导致无障碍跳转失败、Lighthouse 报 duplicate-main 错误、SEO 摘要错乱。
main 必须且只能出现一次,且不能嵌套在 header/nav/footer/aside 里
HTML5 规范强制要求:<main></main> 不能是 <header></header>、<nav></nav>、<footer></footer>、<aside></aside> 或另一个 <main></main> 的后代元素。结构上必须与它们平级,通常直接作为 的子元素。
- 错误写法:
<header><main>...</main></header>—— 屏幕阅读器可能完全忽略该<main></main>,或将其降级为普通容器 - 正确顺序示例:
<header>...</header><main>...</main><footer>...</footer> - SPA 场景下常见坑:在全局 Layout 组件(如 React 的
Layout.tsx)里写<main></main>,导致所有路由共用同一个<main></main>;应由具体页面组件(如Home.tsx)自己包裹
什么内容该放进 main,什么不该
判断标准只有一个:**这块内容是否随 URL 变化、不可复用于其他页面?**
- ✅ 应放进去:
<h1>(页面级标题)、文章正文、商品详情、独立表单(如注册流程)、搜索结果列表、仪表盘核心数据区 - ❌ 绝对禁止:
<nav>(全局导航)、<footer>(版权信息)、<aside>(侧边推荐)、<header>(网站 Logo + 主导航) - ⚠️ 容易混淆:
<nav aria-label="Breadcrumb">(面包屑)和“客服入口”按钮——它们服务主题但不构成主题本身,应放在<section>或<aside>里
main 和 section/article/role="main" 的关系
<main></main> 是页面级语义锚点,不是布局工具;它和 <section>、<article> 是协作关系,不是替代或嵌套关系。
立即学习“前端免费学习笔记(深入)”;
-
<main></main>里可以包含多个<article>(如博客列表)或多个<section>(如“产品介绍”+“用户评价”) - 但
<article>或<section>内部不能再嵌套<main>—— 规范禁止,语义冲突 -
<main>自带隐式role="main",手动加role="main"到同一元素上会导致读屏器重复播报,必须避免 - 旧浏览器(如 IE8)不识别
<main>,若需兼容,可用<div role="main">降级,但仅限必要场景;现代项目优先用原生<main>
真正难的不是写对标签,而是每次渲染前都得问一句:此刻用户看到的,是不是这个 URL 下不可复用、不可剥离的核心?比如电商 SKU 切换后,<main></main> 里的商品图和价格必须实时更新;后台 Tab 切换时,<main></main> 必须只包当前 Tab 的数据区——否则语义就塌了。



















