必须全局唯一、带标题、不塞表单,是防止协作失控的硬边界:<main>错位会导致读屏跳转失败、SEO权重丢失、DevTools报landmark错误;<article>需独立可分发且配标题,混用<section>会污染文档大纲。

<main></main> 必须全局唯一,<section></section> 必须带标题,<nav></nav> 不能塞表单——这些不是“最佳实践”,而是不照做就会让代码在协作中迅速失控的硬边界。
为什么 <div> 套三层比 <code><header></header><nav></nav><main></main> 更难维护
人眼识别结构靠的是语义锚点,不是 class 名。看到 <nav></nav> 就知道这是跳转区域,看到 <main></main> 就能跳过广告和页脚直奔正文;而 <div class="wrapper"><div class="inner"><div class="content"> 这种写法,新人打开 DevTools 要花 10 秒才能确认哪层是真正的内容容器。
<ul><li>浏览器和屏幕阅读器会把 <code><nav></nav> 自动映射为 navigation landmark,但 <div class="nav"> 不会触发任何语义行为
<li>搜索引擎解析 DOM 时,<code><article></article> 和 <section></section> 的标题层级直接参与内容权重计算,<div> 则完全被忽略
<li>VS Code + HTMLHint 插件能自动标出 <code><main></main> 重复、<section></section> 缺标题等错误,但对 class 名毫无反应
<main></main> 放错位置会导致屏幕阅读器“找不到正文”
<main></main> 是辅助技术的导航锚点,不是视觉居中的容器。它被设为 display: none、嵌套在 <section></section> 里、或包裹了侧边栏/顶部 banner,都会让读屏软件按 M 键跳转时失败或跳到错误位置。
- 常见错误:Next.js 或 Vue 布局组件里声明一个
<main></main>,子页面又渲染一个 —— 全局出现两个,读屏只认第一个 - 正确范围:只包用户当前要操作/阅读的核心内容,比如商品列表页的
<ul class="product-list"></ul>,而不是整个的视觉布局 - 性能影响:不增加 HTML 字节数,但会让读屏工具遍历冗余节点,语音响应明显变慢
<section></section> 和 <article></article> 不是 <div> 的升级版,用错就污染文档大纲
<p><code><section></section> 表示有明确主题的逻辑分段,必须配 <h2></h2>–<h6></h6>;<article></article> 表示可独立分发的内容单元(如博客文章、评论、新闻条目)。混用会让屏幕阅读器生成一堆无意义的导航项,用户无法快速定位重点。
立即学习“前端免费学习笔记(深入)”;
- 判断标准:这块内容能否被 RSS 抓取?是否自带标题?是否脱离上下文仍能理解?满足才用
<article></article> - 反例:
<section></section>里只放一个按钮、<article></article>包裹页脚版权信息 —— 这些该用<div> 或更合适的语义标签 <li>SEO 影响:Google 参考文档大纲(outline)评估内容权重,标题层级断裂(比如从 <code><h1></h1>直接跳到<h3></h3>)会弱化主内容识别 -
<header></header>和<footer></footer>可多次出现,但每个都必须服务于其直接父容器(如一个<article></article>可自带<header></header>) -
<nav></nav>必须只含导航链接或带跳转逻辑的按钮;搜索框、登录入口应放在外部,或用<form role="search"></form>单独标记 - 嵌套越界比标签用错更隐蔽:
<main></main>里再套<section></section>合法,但如果子<section></section>实际只是评论列表,就该改用<section><h3>评论</h3>...</section>,否则爬虫误判为“嵌套正文”
最容易被忽略的其实是标题层级和嵌套规则
语义标签本身不报错,但结构错位会让所有语义能力归零。比如 <main></main> 外写了三个 <h1></h1>,或者 <nav></nav> 里混了 <button></button> 却没补 role="link",DevTools 的 Accessibility 面板会直接显示“landmark-uniq”或“navigation role not detected”错误。



















