标签不是的替代品,必须嵌套在内且页面中只能有一个;它专用于包裹唯一、不可复用的核心内容,如文章正文,而非导航、页脚等复用模块。

main 标签不是 body 的替代品,它必须嵌套在 body 内
很多初学者误以为 可以代替 ,这是错误的。HTML5 规范明确要求 必须是 的后代元素,且一个页面只能有一个(或零个),不能嵌套使用。
常见错误现象: 直接放在 下、多个 并存、在 或 里再包一层 —— 这些都会导致语义失效,影响屏幕阅读器识别和 SEO 权重分配。
-
是文档主体容器,所有可见内容都必须在其内;是其中唯一标识「核心内容」的语义区块 - 没有
不报错,但会丢失辅助技术对主内容的快速定位能力 - 服务端渲染(SSR)或静态站点生成器中,若框架自动包裹 layout,需检查是否意外把
包进了或
什么时候该用 main,什么时候不该用
判断依据只有一个:这部分内容是否「对当前页面具有唯一性、不可被其他页面复用」。比如文章正文、产品详情、搜索结果列表——这些是 的典型场景;而导航栏、页脚版权、侧边广告位、面包屑导航,哪怕它们在视觉上位于页面中央,也不属于 。
容易踩的坑: 立即学习“前端免费学习笔记(深入)”; 这是本页唯一的核心内容... 如果因历史原因无法修改 HTML 结构(比如 CMS 输出固定模板),可以用 真实调试中,用浏览器开发者工具的「Accessibility Inspector」查看「Landmark」区域,能立刻验证 搜索引擎爬虫目前普遍支持 另一个隐形陷阱:CSS 重置或 UI 框架(如 Bootstrap)可能给 里塞了全局 或重复使用的 ;或者把整个单页应用(SPA)的根容器(如 —— 实际上,只有路由切换后真正变化的那块内容才应被包裹。
如何正确使用 main 标签
应随路由更新而重新挂载,而不是固定包裹整个 SPA 容器与 aria-main 和 role="main" 的关系
role="main" 或 aria-labelledby 做语义补充,但优先级低于原生 。W3C 明确建议:已有 就不要加 role="main",否则可能触发双重播报(double-announced)问题。 是否被正确识别。若未出现,大概率是嵌套层级错误或被 JavaScript 动态移除。
—— 属于冗余且有潜在兼容风险,而非共存
支持不完整,此时可保留 aria-label 作为降级方案:
SEO 和 SSR 中容易被忽略的细节
,并将其作为内容相关性加权的重要信号。但如果你用 Next.js、Nuxt 或 Remix 等框架,要注意:服务端生成的 HTML 中, 必须包含实际内容,不能是空标签或仅含 loading 占位符。main 元素设了默认 display: block 以外的值(例如 display: contents),这会导致无障碍树中该节点“消失”。务必检查 computed styles。
应放在 app/layout.tsx 的 {children} 外层,而非每个 page.tsx 内部重复定义next/head 或 动态更新,确保 内容与 语义一致(例如标题写「产品 A 详情」,则 内第一级标题也应匹配) 出现次数,确认只有一处且位置合理 —— 自动化 lint 工具如 axe-core 或 html-validate 可加入 CI 检查









