html是语义化结构工程,需以为根、合法嵌套,按功能分区与内容粒度选用标签,避免过度语义化或语义真空,核心是让机器与人一眼理解结构意图。

HTML不是标签堆砌,而是用语义化盒子一层层组织信息的结构工程。基础写法能出页面,但进阶思维决定你能不能快速定位问题、协作不踩坑、适配新需求。
把 当作唯一根容器,所有嵌套必须合法
浏览器解析 HTML 时,会强制修复非法嵌套(比如在 <p></p> 里放 <div>),但修复逻辑不可控,可能破坏样式或 JS 行为。真实项目中常见错误:
<ul>
<li>
<code><h1></h1> 直接放在 外(漏写 或 )→ 触发怪异模式(Quirks Mode),CSS 盒模型失效
<header></header> 塞进 <p></p> → 浏览器自动闭合 <p></p>,后续内容错位<main></main> 出现多次 → 语义冲突,屏幕阅读器只识别第一个正确做法:始终以 开始, 和 并列且唯一;块级容器(如 <section></section>、<article></article>)只嵌套在语义允许的父元素中(查 MDN 的 “Permitted parents” 栏)。
用「功能分区 + 内容粒度」双维度划分结构
新手常按视觉切分(“左边是导航,右边是内容”),但 HTML 进阶要求先问两个问题:
- 这个区域在整个页面中承担什么功能?是全局导航?独立文章?辅助说明?→ 对应
<nav></nav>、<article></article>、<aside></aside> - 里面的内容是否能单独被引用、复用或 RSS 抓取?→ 能则用
<article></article>,不能则用<section></section>
例如一个“热门推荐”模块:
<section aria-labelledby="trending-title"><h2 id="trending-title">热门推荐</h2> <article><h3>标题1</h3> <p>摘要</p></article><article><h3>标题2</h3> <p>摘要</p></article></section>
这里不用 <div class="trending">,因为 <code><section></section> 表明它是逻辑分区,<article></article> 表明每条内容可独立存在——这对 SEO、无障碍、微格式(Microdata)都关键。
避免「过度语义化」和「语义真空」两个极端
语义化不是越多越高级,核心是让机器(搜索引擎、读屏器)和人(其他开发者)一眼看懂结构意图:
- 「过度语义化」:给每个按钮加
<button role="button"></button>→role属性冗余,反而干扰读屏器 - 「语义真空」:全用
<div> + class → 机器无法区分导航、主内容、页脚,SEO 权重分散,无障碍支持归零 <p>实用判断标准:</p> <ul> <li>如果删掉 class 名,仅靠标签还能否大致描述这块内容的作用?不能 → 补语义标签</li> <li>如果加上 ARIA 属性后,原生标签已能表达相同含义?能 → 删 ARIA</li> </ul> <p>比如表单控件:<code><input type="email">已自带语义,无需再加role="textbox";但自定义下拉菜单必须用role="combobox"+aria-expanded等补全。真正卡住人的从来不是标签记不全,而是面对一个新需求时,不知道该从「功能意图」还是「内容独立性」切入去选标签。多看 MDN 上每个语义标签的 “Usage notes” 和实际站点源码(Chrome DevTools → Elements → 右键 “View page source”),比背列表管用得多。











