必须是的直接子元素且全页唯一,否则会被浏览器和辅助技术降级为普通节点,失去“页面主体”语义身份,导致无障碍失效、seo降权及lighthouse报错。

为什么不能嵌套在或里
浏览器和辅助技术(如 NVDA、VoiceOver)靠标签名识别 landmark 区域。<main></main>是 ARIA 定义的 main role 的原生映射,一旦被包裹在 <div class="wrapper"> 或 <code><section></section> 中,它就降级为普通内容节点,失去“页面主体”这一语义身份。
常见错误现象:
-
<header><main>...</main></header> —— <main></main> 被当成页眉的一部分,屏幕阅读器跳过它或误读为辅助内容
-
<div id="app"><main>...</main></div> —— React/Vue 项目常这么写,但会破坏可访问性 API 查询路径
-
<main><section><main>...</main></section></main> —— 多重 <main></main>,浏览器只识别第一个,后续无效
正确做法只有一条:<main></main> 必须是 的直接子元素,且全页唯一。
<article></article> 和 <section></section> 的嵌套边界在哪
两者都支持嵌套,但语义不可互换:<article></article> 表示能脱离当前页面独立存在、可被 RSS 订阅或单独打印的内容单元;<section></section> 是为同一主题下的内容做逻辑分组,本身不具备自足性。
使用场景判断要点:
- 用
<article></article> 包裹整篇新闻、博客正文、用户评论项——它自带隐式 heading 关联能力,搜索引擎会单独索引
- 用
<section></section> 划分“背景”“方法”“结论”这类章节,或“最新评论区”这种有共同主题的区块集合
-
<article></article> 内可嵌套多个 <section></section>,但反过来不行:不能用 <section></section> 包 <article></article> 当作“文章列表容器”,那该用 <main></main> 或带 role="feed" 的 <div>
<p>性能提示:过度嵌套 <code><article><section><article></article></section></article> 会导致 DOM 树层级加深,实测在低端安卓 WebView 中首次绘制(FP)延迟达 80–120ms。
标题层级(<h1></h1>–<h6></h6>)怎么嵌套才不踩坑
标题不是视觉样式工具,而是 DOM 结构锚点。浏览器、SEO 爬虫和屏幕阅读器都依赖它构建内容大纲(outline)。跳级、重复、错位都会导致 outline 断裂。
关键约束:
- 每个页面严格只用一个
<h1></h1>,代表页面核心主题,通常出现在 <main></main> 开头
-
<h2></h2>–<h6></h6> 必须按逻辑深度嵌套,禁止 <h1></h1> → <h3></h3> 跳级;也不允许 <h2></h2> 出现在 <main></main> 外(比如塞进 <header></header> 里当网站名)
-
<article></article> 和 <section></section> 可自带隐式标题上下文:它们内部的首个 <h1></h1> 会被视为该区块的标题,而非全局 <h1></h1> —— 但前提是该区块本身有明确语义边界
容易忽略的一点:CSS 隐藏标题(display: none)会让它从 outline 中消失,但语义仍存在;若真不需要语义标题,应删掉标签,而非仅隐藏。
<header></header> 和 <footer></footer> 多级复用时怎么避免语义污染
<header></header> 和 <footer></footer> 不是页面级专属标签,它们可在 、<article></article>、<section></section> 内部重复出现,但每处都必须匹配其父容器的上下文。
典型误用:
- 在
<article></article> 里放网站 Logo 和主导航 —— 这属于页面级 <header></header>,应放在 顶层
- 把“编辑于 2026-08-25”写在页面
<footer></footer> 里,却同时在 <article></article> 底部也放一模一样的版权信息 —— 后者应只含文章级元数据(作者、发布时间、标签)
- 用
<header></header> 包按钮、搜索框、广告位 —— 这些不属于“引导性内容”,应归入 <nav></nav> 或普通 <div>
<p>检查方式:右键 Chrome DevTools Elements 面板中任一 <code><header></header>,看它的父节点是否具备明确的主题容器(如 、<article></article>),再确认其子内容是否真正服务于该容器的开头/结尾意图。
浏览器和辅助技术(如 NVDA、VoiceOver)靠标签名识别 landmark 区域。<main></main>是 ARIA 定义的 main role 的原生映射,一旦被包裹在 <div class="wrapper"> 或 <code><section></section> 中,它就降级为普通内容节点,失去“页面主体”这一语义身份。
常见错误现象:
-
<header><main>...</main></header>——<main></main>被当成页眉的一部分,屏幕阅读器跳过它或误读为辅助内容 -
<div id="app"><main>...</main></div>—— React/Vue 项目常这么写,但会破坏可访问性 API 查询路径 -
<main><section><main>...</main></section></main>—— 多重<main></main>,浏览器只识别第一个,后续无效
正确做法只有一条:<main></main> 必须是 的直接子元素,且全页唯一。
<article></article> 和 <section></section> 的嵌套边界在哪
两者都支持嵌套,但语义不可互换:<article></article> 表示能脱离当前页面独立存在、可被 RSS 订阅或单独打印的内容单元;<section></section> 是为同一主题下的内容做逻辑分组,本身不具备自足性。
使用场景判断要点:
- 用
<article></article>包裹整篇新闻、博客正文、用户评论项——它自带隐式heading关联能力,搜索引擎会单独索引 - 用
<section></section>划分“背景”“方法”“结论”这类章节,或“最新评论区”这种有共同主题的区块集合 -
<article></article>内可嵌套多个<section></section>,但反过来不行:不能用<section></section>包<article></article>当作“文章列表容器”,那该用<main></main>或带role="feed"的<div> <p>性能提示:过度嵌套 <code><article><section><article></article></section></article>会导致 DOM 树层级加深,实测在低端安卓 WebView 中首次绘制(FP)延迟达 80–120ms。标题层级(
<h1></h1>–<h6></h6>)怎么嵌套才不踩坑标题不是视觉样式工具,而是 DOM 结构锚点。浏览器、SEO 爬虫和屏幕阅读器都依赖它构建内容大纲(outline)。跳级、重复、错位都会导致 outline 断裂。
关键约束:
- 每个页面严格只用一个
<h1></h1>,代表页面核心主题,通常出现在<main></main>开头 -
<h2></h2>–<h6></h6>必须按逻辑深度嵌套,禁止<h1></h1>→<h3></h3>跳级;也不允许<h2></h2>出现在<main></main>外(比如塞进<header></header>里当网站名) -
<article></article>和<section></section>可自带隐式标题上下文:它们内部的首个<h1></h1>会被视为该区块的标题,而非全局<h1></h1>—— 但前提是该区块本身有明确语义边界
容易忽略的一点:CSS 隐藏标题(
display: none)会让它从 outline 中消失,但语义仍存在;若真不需要语义标题,应删掉标签,而非仅隐藏。<header></header>和<footer></footer>多级复用时怎么避免语义污染<header></header>和<footer></footer>不是页面级专属标签,它们可在、<article></article>、<section></section>内部重复出现,但每处都必须匹配其父容器的上下文。典型误用:
- 在
<article></article>里放网站 Logo 和主导航 —— 这属于页面级<header></header>,应放在顶层 - 把“编辑于 2026-08-25”写在页面
<footer></footer>里,却同时在<article></article>底部也放一模一样的版权信息 —— 后者应只含文章级元数据(作者、发布时间、标签) - 用
<header></header>包按钮、搜索框、广告位 —— 这些不属于“引导性内容”,应归入<nav></nav>或普通<div> <p>检查方式:右键 Chrome DevTools Elements 面板中任一 <code><header></header>,看它的父节点是否具备明确的主题容器(如、<article></article>),再确认其子内容是否真正服务于该容器的开头/结尾意图。
- 每个页面严格只用一个











