main 标签必须且只能出现一次,是 HTML5 与 WCAG 2.1 的强制要求;它作为语义锚点供屏幕阅读器跳转和搜索引擎识别核心内容,须直接位于 body 下、不嵌套于其他语义标签内,并确保内容唯一、不可复用。

main 标签必须且只能出现一次,这不是建议,而是 HTML5 规范与 WCAG 2.1 的强制要求。它不是视觉容器,而是语义锚点——屏幕阅读器靠它实现「按 M 键直达主内容」,搜索引擎靠它识别页面核心主题。违反唯一性,会导致跳转失效、Lighthouse 报 duplicate-main、SEO 摘要错乱,且浏览器不会报错,容易被忽视。
确保 main 直接位于 body 下,不嵌套在任何语义区块内
规范明令禁止 <main> 作为 <header>、<footer>、<nav>、<article> 或 <section> 的子元素。语义上,主体内容不可能“属于”页眉或页脚。
- ❌ 错误:
<header><main>...</main></header>→ Lighthouse 明确报错,读屏器大概率跳过 - ✅ 正确:所有顶层语义区块并列于
<body>下,如<header></header><main></main><footer></footer> - ⚠️ 注意:
<header>可以作为<main>的直接子元素,但仅限本页专属标题(如文章<h1>+ 发布时间),不能塞全站 Logo 和导航
验证页面是否真只有一个 main 实例
不能依赖肉眼检查或“看起来正常”,必须实操验证:
- 打开开发者工具(F12),切换到 Elements 面板,按 Ctrl+F(Windows)或 Cmd+F(macOS),搜索
<main> - 匹配结果应严格为**一对**开始与结束标签;注意闭合是否完整、是否被注释包裹
- SPA 场景下需切换路由后再次搜索——React/Vue 组件若各自声明
<main>,hydration 后 DOM 中会残留多个实例 - 服务端模板(如 EJS/Twig)中,列表页与详情页共用同一段包裹逻辑,易生成嵌套或并列的多个,需加路由判断控制输出
main 内容必须是当前 URL 独有、不可复用的部分
判断标准非常实在:如果这块内容复制粘贴到另一个页面还能原样用,那它就不该进 <main>。
立即学习“前端免费学习笔记(深入)”;
- ✅ 应放:文章正文、商品详情、独立表单、搜索结果列表、404 提示文案
- ❌ 必须排除:全局导航(
<nav>)、页脚版权(<footer>)、面包屑、右侧推荐栏、登录框、“关注我们”模块 - ⚠️ 多区块首页(如热榜+最新+推荐)应统一包裹在一个
<main>内,用<section>划分,而非给每个区块单独加<main>
增强可访问性:显式添加 aria-label 或 aria-labelledby
虽然 <main> 自带隐式 role="main",但显式提供上下文能提升兼容性:
- 在
<main>开始标签中添加aria-labelledby="main-title",并确保对应 ID 元素存在且含描述性文本(如<h1 id="main-title">欢迎来到个人博客</h1>) - 若无合适标题元素,可用
aria-label="文章正文区域"直接说明用途 - 避免空值或泛泛而谈(如
aria-label="内容"),需具体、有意义



















