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

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











