标签是页面唯一主要内容入口,每页仅能有一个且不可嵌套于其他分区元素内,用于保障可访问性与seo;其内容须为当前视图独有、不可复用,禁止包含全局导航、页脚等复用组件。

main 标签不是“可有可无的语义装饰”,它是浏览器和读屏软件(如 NVDA、VoiceOver)识别页面“唯一主要内容入口”的关键信号。用错或不用,直接影响可访问性与 SEO。
为什么一个页面只能有一个 <main></main>
规范强制要求每页最多出现一次 <main></main>,且不得嵌套在 <article></article>、<aside></aside>、<footer></footer>、<header></header>、<nav></nav> 等分区元素内。原因很实际:
- 辅助技术依赖它快速跳转到核心内容,多个
<main></main>会让屏幕阅读器困惑“到底哪块才是主舞台” - 搜索引擎会弱化重复或冲突的
<main></main>区域的权重,甚至忽略其中内容 - 单页应用(SPA)路由切换时若未动态更新
<main></main>位置,旧内容可能残留,新内容被跳过
<main></main> 里能放什么、不能放什么
它只该包裹“当前视图下独一无二、不可复用”的内容。判断标准很简单:如果这块内容复制粘贴到另一个页面还能原样用,那它就不该进 <main></main>。
- ✅ 允许:
<article></article>(博客正文)、<ol></ol>(商品列表)、<form></form>(独立提交表单)、纯文本段落 - ❌ 禁止:
<nav></nav>(全局导航)、<footer></footer>(页脚版权)、<aside></aside>(侧边推荐)、<header></header>(网站 Logo + 主导航) - ⚠️ 注意:
<header></header>作为<main></main>的子元素是允许的——但仅限“本篇文章的标题与元信息”,不是整个网站头部
兼容性与 SPA 路由中的常见翻车点
IE 完全不支持 <main></main>,但现代项目基本已无须考虑;真正容易出问题的是动态渲染场景:
- Vue/React 中用
v-if或条件渲染切换<main></main>内容时,若没确保每次只存在一个有效实例,可能 DOM 中残留多个<main></main> - 服务端渲染(SSR)中,
<main></main>若被包裹在<div id="app"> 外层,而框架挂载点又在内部,会导致结构断裂 <li>测试时可用 DevTools 运行 <code>document.querySelectorAll('main').length快速验证是否超标
最常被忽略的一点:它不是视觉容器,不带默认样式。很多人加了 <main></main> 却没配 CSS,结果发现布局没变化——这恰恰说明它干的是语义活,不是排版活。











