必须且只能出现一次,不可嵌套在等结构性元素内,否则破坏 landmark 唯一性、引发屏幕阅读器误读及 seo 扣分; 需含标题以维持语义; 表示可剥离的附属性内容; 适用于所有可编号引用的独立内容单元。

<main></main> 必须且只能出现一次,且不能嵌套在 <article></article>、<aside></aside>、<footer></footer>、<header></header>、<nav></nav> 内——这是 W3C 明确规定的约束,不是建议。
为什么 <main></main> 不能嵌套在 <article></article> 里
浏览器和辅助技术(如屏幕阅读器)把 <main></main> 当作页面唯一的内容焦点区域,一旦嵌套,会破坏 landmark role 的唯一性。ARIA 规范要求 role="main" 在整个 DOM 中只能存在一个实例;而 <article></article> 自带 role="article",其子元素若再设 <main></main>,会导致语义冲突和读屏器跳过或重复播报。
常见错误现象:
- 屏幕阅读器朗读两次“主要内容”
- Chrome DevTools 的 Accessibility 面板报出 “Duplicate landmark” 错误
- SEO 工具(如 Lighthouse)在「结构化数据」审计中扣分
正确做法:
- 把文章正文直接放在
<article></article>内部,无需额外包一层<main></main> - 整页的主内容区用顶层
<main></main>包裹(例如博客列表页),而单篇详情页则用<article></article>作为主体容器 - 如果页面有多个独立内容块(如首页含推荐文章+最新动态),用多个
<article></article>并列,外层用<main></main>统一包裹
<section></section> 必须带标题才能合法使用
W3C 规定 <section></section> 是“有主题的、可被大纲算法识别的区块”,没有标题(<h1></h1>–<h6></h6>)时,它就退化为普通容器,语义丢失,且可能被解析为无意义的 <div>。
<p>实际影响:</p>
<ul>
<li>HTML5 outline 算法无法生成正确文档大纲</li>
<li>某些无障碍工具(如 axe-core)会警告 “Section lacks heading”</li>
<li>搜索引擎对无标题 <code><section></section> 的内容权重降低
注意点:
- 标题可以是
<h2></h2>或更深层级,但不能跳级(比如上一级是<h2></h2>,下一级<section></section>里却用<h4></h4>) - 允许用
<hgroup></hgroup>合并主副标题,但不推荐——多数浏览器未完全支持其语义解析 - 如果只是视觉分隔(如卡片间距、背景色块),优先用 CSS(
margin/background)而非<section></section>
<aside></aside> 不等于“侧边栏”,而是“与当前上下文相关但可独立移除的内容”
开发者常把所有右侧栏都写成 <aside></aside>,但它的语义核心是“附属性”和“可剥离性”。比如一篇技术文章里的代码解释、术语注释、作者简介,才是典型的 <aside></aside>;而全站通用的广告位、用户登录框、全局导航,属于页面级结构,应归入 <header></header>、<nav></nav> 或 <footer></footer>。
典型误用场景:
- 在
<main></main>外、直接子级放<aside></aside>—— 它必须依附于某个流内容上下文(如紧邻<article></article>) - 用
<aside></aside>包裹搜索框或分类菜单 —— 这些是功能组件,不是内容附属物 - 给
<aside></aside>加position: fixed脱离文档流 —— 会切断其与上下文的语义关联
判断依据:删掉这块内容,原文是否仍逻辑自洽、信息完整?如果是,才适合 <aside></aside>。
<figure></figure> 和 <figcaption></figcaption> 不只用于图片
很多人以为 <figure></figure> 就是 <img> 的父容器,其实它涵盖任何“可被编号引用的独立媒体或内容单元”,包括代码块、表格、SVG 图表、甚至引文(<blockquote></blockquote>)。
关键规则:
-
<figcaption></figcaption>必须是<figure></figure>的**第一个或最后一个子元素**,否则语义失效 - 即使没有可视标题,也建议保留空
<figcaption></figcaption>(如<figcaption></figcaption>),避免被解析为无说明媒体 - 不要用
<figure></figure>包裹纯装饰性图片(如背景图、分割线),它们不属于“可引用内容”
示例(合法):
<figure><pre class="brush:php;toolbar:false;"><code>console.log("Hello");</code>
这个结构让代码块在无障碍树中被识别为“带说明的独立内容”,比单纯用 <pre class="brush:php;toolbar:false;"></pre> 更准确。
最易被忽略的点:语义标签不是“换汤不换药”的 div 替代品,它们触发浏览器内置的 ARIA role 注入、影响 DOM outline、改变辅助技术遍历路径——写对了,机器能懂;写错了,比不用还糟。











