HTML语义化标签失效主因是误用:section缺标题即退化为div,main重复或嵌套破坏唯一性,div在纯布局、ARIA封装等场景反而是合理选择;标题层级断裂比不用语义标签危害更大。

HTML语义化标签不是“不好用”,而是被当成样式工具用了——一旦你拿 <section> 当 <div> 用,或把 <main> 套在导航栏外面,它立刻就失效了。
为什么 <section> 写了却没效果?
浏览器和读屏器根本没把它当“节”处理,因为 W3C 要求它必须带标题。没 <h2>–<h6>,它就等于 <div>。
- 常见错误:
<section class="grid-3"><p>欢迎关注我们</p></section>—— 无标题、不可分发、不参与大纲生成 - 正确做法:先写标题,再包
<section>,例如<h3>技术参数</h3><section>...</section> - 验证方式:Chrome DevTools → Elements → 右键
<section>→ “Inspect Accessibility Properties”,看是否有 heading role - 后果:Lighthouse 报 “Heading levels should only increase by one”,或整页大纲(outline)缺失节点
<main> 怎么越用越乱?
它不是“视觉居中那块”,而是全页唯一的内容锚点。出现两次、被 <section> 包裹、里面塞了导航栏,都会让辅助技术彻底迷路。
- Next.js / React 布局组件里写一个
<main>,子页面又渲染一个 → DOM 中实际存在两个,屏幕阅读器只认第一个 -
<body><section><main>...</main></section></body>→<main>的 role 被降级为 section-local,不再是页面主干 - 正确结构:
<body><header>...</header><main>只放正文/表单/商品列表等用户真正要操作的部分</main><footer>...</footer></body> - 兼容提示:IE9 需加
display: block,但现代项目可忽略
哪些地方必须坚持用 <div>?
<div> 不是语义化失败的标志,而是语义“真空区”的合理占位符——当结构只为布局、状态切换或 ARIA 封装服务时,强行套语义标签反而污染结构。
立即学习“前端免费学习笔记(深入)”;
- 纯 Flex/Grid wrapper:如
<div class="grid-cols-3 gap-4">,内部无标题、无独立主题,仅控制对齐与间距 - 动态组件外壳:Vue 的
<Card>、React 的<Modal>,语义由内部内容决定,外层用<div>更安全 - ARIA 区域包装器:如
<div role="region" aria-labelledby="search-label">,比硬套<section>更精准传达意图 - 轮播图/手风琴/标签页:子项是状态切换的一部分,不是独立内容单元,用
<div>+aria-controls比嵌套多个<section>更合理
标题层级断裂比不用语义标签更危险
辅助技术靠 <h1>–<h6> 构建文档树。跳级、缺 <h1>、多个 <h1>,会让视障用户完全失去上下文。
- 全页只允许一个
<h1>(代表页面主题),<h2>分割主模块(如“服务介绍”“客户案例”) - 避免 CSS 隐藏
<h1>却不加aria-hidden="true"→ 屏幕阅读器仍会朗读,造成重复干扰 - 别用
<h2>写 logo 文字(应为<h1>或纯文本 +aria-label) - 检查工具:Lighthouse 的 “Document does not have a main landmark” 往往根源不在
<main>,而在标题断层导致大纲无法生成
语义化真正的门槛不在“会不会写”,而在“敢不敢删”——删掉所有没标题的 <section>,删掉包裹非主内容的 <main>,删掉用来撑样式的 <nav>,剩下那些才真正起作用。



















