应直接使用原生语义化标签:、、(仅一次且为直系子元素)、(须带标题)、(仅用于主要导航),避免用div模拟或错误嵌套。

用 <header></header> 和 <footer></footer> 时,别套在 div 里再加 class
很多人写语义化结构,是先写一个 <div class="header">,再自己加 CSS 去模拟 <code><header></header> 行为——这等于没用语义。浏览器、屏幕阅读器、SEO 爬虫只认原生标签名,不看你 class 叫什么。
正确做法就是直接用 <header></header>,它天然具备 sectioning root 行为(影响大纲生成),且默认有隐式 ARIA role。
- 一个页面可以有多个
<header></header>:比如<article></article>内部也能有自己的<header></header>,用于该文章的标题+元信息 -
<footer></footer>同理,不是只能放在页面最底下;<aside></aside>里也可以有<footer></footer> - 避免嵌套错误:
<header></header>不能作为<main></main>的子元素再包一层<div>——这会让辅助技术误判层级 <h3> <code><main></main>只能出现一次,且不能被<article></article>、<aside></aside>包裹这是最常被忽略的约束。
<main></main>表示文档中与当前页面主题最相关的内容主体,整个页面生命周期里只允许存在一个,且必须是的直接子元素(或至少不被其他 sectioning content 包裹)。常见错误现象:
HTML5 outline algorithm失效、NVDA 报告“multiple main landmarks”警告、Lighthouse 语义化评分掉档。立即学习“前端免费学习笔记(深入)”;
- 错误写法:
<article><main>...</main></article>——<main></main>被降级为普通内容容器,失去 landmark 意义 - 正确结构:
<header>...</header><main>...</main><aside>...</aside><footer>...</footer> - 如果页面有 tab 切换,每次切换后要确保新内容区域仍属于同一个
<main></main>,而不是动态插入新的<main></main>
<section></section>不是 div 替代品,得有标题才成立W3C 明确说:
<section></section>必须有自己独立的标题(<h1></h1>–<h6></h6>),否则它和<div> 在语义上完全等价,还多占一个 DOM 节点。 <p>换句话说,没有标题的 <code><section></section>就是语义污染——既没提升可访问性,又干扰大纲生成。- 适用场景:博客文章的「背景」「方法」「结论」三块;产品页的「参数」「评价」「售后」分组
- 反例:
<section class="grid-container"></section>—— 纯布局用途,该用<div> <li>注意 <code><section></section>和<article></article>的区别:<article></article>是可独立分发/复用的内容(如微博、新闻条目),<section></section>是逻辑分组,不可脱离上下文存在 - 应该用
<nav></nav>:主导航栏、页脚的站点地图链接组、文章内「上一篇/下一篇」 - 不该用
<nav></nav>:评论区的用户头像链接、文章末尾的「相关推荐」(属于<aside></aside>)、面包屑(用<nav aria-label="breadcrumb"></nav>是例外,但需加 label) - 性能提示:某些旧版 IE 对
<nav></nav>的 CSS 渲染有 bug,若需兼容,可用display: block显式重置
用
<nav></nav>前先问:这个链接列表是否真的构成「导航」很多项目把所有横向菜单、侧边栏链接、甚至「关注我们」社交图标都塞进
<nav></nav>,结果导致屏幕阅读器用户一进页面就被迫听十几秒导航播报。<nav></nav>的语义是「主要导航区块」,不是「所有带链接的容器」。W3C 推荐每个页面最多 2–3 个<nav></nav>,且需有aria-label或<h2></h2>明确其作用。 - 错误写法:











