语义化标签的价值不在于"少写几个 div",而在于让搜索引擎和屏幕阅读器能直接读懂页面的结构层级;section 和 article 的分界线是内容能否脱离上下文独立成立;而 div 重构的正确姿势是先把 landmark 骨架搭好,再逐层替换,最后保留 div 做工具体的布局容器。
section 和 article 到底有什么区别?
结论:article 装的是"能单独拎出去还存在"的内容,section 装的是"必须依附上下文才成立"的主题分组。
判断方法很简单——把这段内容单独复制到 RSS 阅读器或分享卡片里,还读得通吗?能,就用 article。一篇博客正文、一条用户评论、一个论坛帖子、一张商品卡片,都是 article。而"这篇文章的正文"下面的"相关参数说明""常见问题"分区,离开文章就没意义,用 section。
两条硬规则要记住:第一,section 必须带标题(h2–h6),没有标题的分组说明它只是一个样式容器,应该用 div;第二,article 可以嵌套 article,比如文章里的评论列表,每一条评论都是独立 article,这是符合规范的,不是错误。
规范层面,HTML5 在 2014 年成为 W3C 推荐标准,现在由 WHATWG 维护 Living Standard,article 的定义是"可独立分发或复用的完整内容单元",section 是"文档中的一个主题性分组"。
语义化标签能带来什么实际收益?
结论:三条可验证的收益——屏幕阅读器导航、搜索引擎结构理解、团队维护成本下降。
无障碍方面最直接。header、nav、main、aside、footer 会分别映射为 ARIA landmark 角色 banner、navigation、main、complementary、contentinfo。NVDA 用户按 D 键就能在所有 landmark 之间跳转,VoiceOver 用户通过转子(Rotor)列出页面区域。注意一个细节:header/footer 只有在不嵌套于 article 或 section 内时才映射为 banner/contentinfo,嵌套进去就降级为普通容器。
SEO 方面,Google 明确表示语义标签是弱信号,但 main 里的正文、唯一 h1、article 的发布时间(配合 datetime 属性)都影响内容抽取。结构化程度高的页面在被 AI 引擎抓取时更容易切分出独立段落。
可维护性上,<nav> 比 <div class="nav"> 少一个类名依赖,改版时不会因为类名被复用而误伤样式。
怎么把一坨 div 重构成语义化结构?
结论:按"骨架 → 内容单元 → 交互元素 → 列表"四步走,不要一次性全改。
第一步,搭 landmark 骨架:header、nav、main、aside、footer。整个页面只能有一个 main,且 main 不能放进 article 内部。
第二步,判断内容单元:对每个块问上面那个"能否独立分发"的问题,能则 article,否则看有没有主题标题,有则 section,都没有就保留 div。
第三步,替换交互元素——这是最容易被忽略、收益最大的一步。可点击的 div 必须改成 button 或 a。原因很具体:div 不在 Tab 焦点序列里,键盘用户根本按不到,需要手动补 tabindex="0"、role="button" 和 keydown 处理 Enter/Space,成本远高于直接换标签。
第四步,列表型结构一律用 ul/ol/li,导航菜单、卡片列表、面包屑都是典型场景。屏幕阅读器会播报"列表,共 6 项",而 div 堆砌只会播报一串链接。
第五步,表单补 label,一组单选或多选外面套 fieldset + legend。
验证环节用三个工具:W3C Nu Html Checker(validator.w3.org/nu)、axe DevTools 浏览器扩展、Lighthouse 无障碍审计,最后开一次屏幕阅读器实测。
什么时候用 div 才是对的?
结论:当容器不承载任何语义、纯粹服务于 CSS 布局或 JS 挂载时,div 就是正确答案,不是技术债。
Grid 和 Flex 布局经常需要一层无意义包裹,这种场景写 section 反而是错的。判断标准就一条:这个标签能不能在文档大纲里说出一句"它是什么"。说不出,就用 div。
反过来,常见的误用是"为了语义化把什么都包成 section"。一个没有标题、没有独立主题的 section,在规范里属于错误用法,在无障碍树里也不会产生任何额外信息,纯属自欺欺人。
收束一下:article 和 section 的分界线是内容可独立性,section 必须有标题,div 只做无语义的布局容器;重构顺序是 landmark 骨架优先、交互元素次之,最后用自动化工具加屏幕阅读器双重验证。语义化不是把 div 清零,而是让每个标签都能回答"我是什么"。