<section>必须含<h2>–<h6>才构成合法语义区块,否则被降级为普通流内容、大纲消失,Lighthouse报错;<div>明确无语义,适用于纯布局、样式分组或动态容器。

section 必须带 <h2> 才算合法语义区块
浏览器和读屏软件不会把没标题的 <section> 当成独立章节——它会被降级为普通流内容,大纲里消失,Lighthouse 直接报“<section> missing heading”错误。W3C 明确要求每个 <section> 应含 <h1>–<h6>,不是“建议”,是语义成立的前提。
常见错误包括:
– 用 <section class="carousel-controls"> 包左右箭头(纯交互容器,无主题)
– 在页脚写 <section><p>© 2026</p></section>(应直接用 <footer>)
– 嵌套 <section><section> 却只在外层有 <h2>(内层缺失标题,语义断裂)
div 是唯一明确声明“此处无语义”的容器
它不参与文档大纲,不被读屏器识别为可跳转节点,也不影响 SEO 权重分配——这不是缺陷,是设计目的。当你只是加个背景色、设个 flex 容器、挂个 id="modal-root",<div> 就是最诚实的选择。
真实项目中高频使用场景:
– CSS Grid / Flex 布局的直接父容器(如 <div class="grid-container">)
– React/Vue 组件根节点(<div id="app"> 或 <div class="product-card">)
– 纯样式分组(<div class="btn-group">)
– 动态插入区域(<div id="toast-container">)
立即学习“前端免费学习笔记(深入)”;
性能与渲染开销完全一致,但兼容性有硬边界
<section> 和 <div> 都是轻量标签,无默认 margin/padding,CSS 选择器行为相同,V8 和 Blink 渲染路径也无差异。所谓“性能对比”根本不存在。
真正要注意的是兼容性断层:
– IE ≤ 8 完全不识别 <section>,JS 查不到、CSS 不生效、样式继承中断
– 若项目仍需支持旧 IE,必须用 document.createElement('section') + HTML5 Shiv,或直接回退到 <div role="region">
– <div> 从 IE6 起就稳如磐石,无需任何 polyfill
DOM 查询漂移比你想象中更常见
用 document.querySelector('.sidebar') 本意是选侧边栏容器,但如果某天同事把 <div class="sidebar"> 改成 <section class="sidebar">,而你 JS 里还有 el.parentElement.tagName === 'DIV' 这类判断,逻辑就崩了。
这类问题往往在重构后期才暴露:
– CSS 框架(如 Bootstrap)某些重置规则对 <section> 设了 margin-top,导致视觉错位
– 测试用例里 mock DOM 时 hardcode 了 <div>,实际跑起来匹配失败
– SSR 渲染后客户端 hydrate 阶段因标签不一致触发 Vue/React 警告
语义标签的价值不在“看起来高级”,而在“让机器准确理解你的意图”。该用 <section> 的地方不用,结构就残缺;不该用却硬套,反而制造噪音。最常被忽略的点是:**标题不是装饰,是语义锚点——没有 <h2> 的 <section>,等于没写。**



















