标签纯语义化,声明页面唯一不可复用的核心内容区域,须严格唯一且不得嵌套于/等元素内,否则破坏语义并导致辅助技术失效。

<main></main>不是定义业务逻辑的标签,它只负责声明“当前 URL 对应的、不可复用的核心内容区域”——浏览器不执行它,JS 不监听它,后端不解析它。它的作用纯语义:告诉屏幕阅读器“按 M 键跳到这里”,告诉 Lighthouse “这部分是主内容评分依据”,告诉搜索引擎“摘要优先从这里抽”。
怎么确认页面只有一个<main></main>标签
浏览器不会报错,但多个 <main></main> 会让辅助技术失效。必须手动验证:
- 打开开发者工具(F12),在 Elements 面板按
Ctrl+F(Windows)或Cmd+F(macOS),搜索<main></main> - 检查匹配结果是否严格只有 1 个开始标签和 1 个结束标签
- 特别注意 SPA 场景:React/Vue 中每个路由组件都写
<main>{children}</main>,最终 DOM 会叠加出多个;应只由最外层路由容器(如App.tsx或page.tsx)包裹一次 - 服务端模板(EJS/Twig)中,避免列表页与详情页共用同一套
<main></main>包裹逻辑,导致嵌套或并列渲染
<main></main>为什么不能嵌套在<header></header>或<nav></nav>里
HTML5 规范明令禁止 <main></main> 作为 <header></header>、<nav></nav>、<footer></footer>、<aside></aside> 的后代元素——这不是样式问题,是语义冲突。
- 错误写法:
<header><main>...</main></header>→ 屏幕阅读器可能完全忽略该<main></main>,或将其降级为普通容器 - 正确结构:必须与
<header></header>、<nav></nav>、<footer></footer>平级,且直接隶属于 -
<header></header>可以作为<main></main>的子元素存在,但仅限“本页专属标题与元信息”,比如文章页的<h1></h1>和发布时间,而非网站全局 Logo + 主导航
<main></main>里该放什么、不该放什么
判断标准只有一个:这块内容是否“随 URL 变化、不可复用”。复制粘贴到另一个页面还能原样用?那它就不属于 <main></main>。
- ✅ 应包含:
<article></article>、<ol></ol>(商品列表)、<form></form>(独立提交表单)、<section></section>(如“用户评价”子模块) - ❌ 必须排除:
<nav></nav>(全局导航)、<footer></footer>(版权信息)、<aside></aside>(侧边推荐)、面包屑、登录框、固定侧栏 - ⚠️ 常见误判:首页的“热门推荐”区块——若它不随路由变化(比如始终是通用运营位),就该用
<section></section>,而不是塞进<main></main>
最容易被忽略的是:SPA 中动态更新内容时,<main></main> 标签本身位置不能变,只替换其子节点;不要用 JS 整体移除再重建 <main></main>,否则读屏器会丢失焦点锚点。


















