大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
HTML 文档结构
这一课你将能做到
- 写出一个带完整 head 配置(charset、viewport、title、description)的 HTML5 页面骨架
- 用 header / nav / main / article / section / aside / footer 搭出语义化页面布局,并说明每个标签的语义边界
- 解释 DOCTYPE、meta viewport 的作用,知道缺失时浏览器会发生什么
为什么要学
上一课我们写出了第一个页面,但那个页面只有 h1 和 p,像一间没隔墙的毛坯房。真实网站的页面有顶部导航、侧边栏、主内容区、底部版权——这些区域怎么划分,直接决定三件事:
- 搜索引擎能不能看懂你的页面:Google 爬虫会优先抓
<main>里的内容,忽略<footer>里的链接堆砌。 - 屏幕阅读器能不能导航:视障用户靠 landmarks(地标)跳转,一堆
<div>等于没有路标。 - 团队协作成本:
div.div1 > div.div2和<main><article>,哪个三个月后还能看懂,不言而喻。
人话:语义化标签就是给房间贴门牌——「主卧」「厨房」「卫生间」,而不是「房间1」「房间2」。
先建立图像
一个典型页面的区域划分:
┌─────────────────────────────────────┐
│ header (Logo + 网站名) │
├─────────────────────────────────────┤
│ nav (主导航菜单) │
├──────────────────┬──────────────────┤
│ main │ aside │
│ ┌────────────┐ │ (侧边栏: │
│ │ article │ │ 相关文章、 │
│ │ 正文文章 │ │ 广告) │
│ │ ┌────────┐ │ │ │
│ │ │section │ │ │ │
│ │ └────────┘ │ │ │
│ └────────────┘ │ │
├──────────────────┴──────────────────┤
│ footer (版权、备案、友情链接) │
└─────────────────────────────────────┘
对应关系:main 是客厅(一个页面只能有一个),article 是一件完整家具(可以独立搬走,比如一篇博客),section 是家具里的抽屉(文章里的章节)。
跟着做
步骤 1:最小完整骨架
新建 structure.html,输入:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="学习 HTML 文档结构的示例页面">
<title>文档结构演示</title>
</head>
<body>
<p>骨架完成</p>
</body>
</html>
逐行解释 head 里的四个关键配置:
<!DOCTYPE html>:必须在第一行,声明这是 HTML5 文档。漏掉它浏览器会进入「怪异模式」,盒模型计算方式都会变。<meta charset="UTF-8">:必须放在 head 的最前面(规范要求在前 1024 字节内),否则中文可能乱码。<meta name="viewport" ...>:告诉手机浏览器「页面宽度 = 设备宽度,初始缩放 1 倍」。没有它,手机会把页面按 980px 宽渲染再缩小,字小得没法看。<meta name="description">:不显示在页面上,但会出现在搜索引擎结果的摘要里。
步骤 2:用语义化标签搭布局
把 body 替换为:
<body>
<header>
<h1>技术博客</h1>
<nav>
<ul>
<li><a href="/">首页</a></li>
<li><a href="/articles">文章</a></li>
<li><a href="/about">关于</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h2>HTML5 语义化入门</h2>
<p>发布时间:<time datetime="2026-10-06">2026年10月6日</time></p>
<section>
<h3>什么是语义化</h3>
<p>用含义明确的标签代替无意义的 div……</p>
</section>
<section>
<h3>为什么要语义化</h3>
<p>搜索引擎和屏幕阅读器都依赖语义……</p>
</section>
</article>
<aside>
<h3>相关阅读</h3>
<ul>
<li><a href="#">CSS 布局基础</a></li>
<li><a href="#">SEO 实战</a></li>
</ul>
</aside>
</main>
<footer>
<p>© 2026 技术博客 · 京ICP备xxxx号</p>
</footer>
</body>
浏览器打开后按 F12 → Elements,鼠标悬停在 <main> 上,能看到它高亮的区域——这就是「地标」。
步骤 3:验证嵌套规则
语义化标签有隐含的使用规则,故意写错再改正:
<!-- 错误示范:article 里套 header 是允许的,但 main 不能出现两次 -->
<main>
<article>文章一</article>
</main>
<main>
<article>文章二</article> <!-- 错!一个页面只能有一个 main -->
</main>
正确做法:多篇并列文章应该这样——
<main>
<h1>文章列表</h1>
<article>
<h2>文章一标题</h2>
<p>摘要……</p>
</article>
<article>
<h2>文章二标题</h2>
<p>摘要……</p>
</article>
</main>
每个 article 都是独立完整的内容单元,可以单独被订阅器(RSS)抓走。
步骤 4:查看无障碍树
Chrome F12 → Elements → 右上角切换到「Accessibility」面板,点击页面中的 <header>,能看到它的角色是 banner;<main> 是 main;<nav> 是 navigation。屏幕阅读器用户按快捷键就能在这些地标间跳跃——这就是语义化的实际价值,不只是「代码好看」。
讲清楚要点
- DOCTYPE 是模式开关:
<!DOCTYPE html>触发标准模式;缺失或写错触发怪异模式,浏览器会模拟 1990 年代的 bug 行为,宽度计算、字体继承全乱。 - head 是控制室:页面看不到 head 内容,但它决定编码、移动端缩放、SEO 摘要、外部资源引入。charset 必须最先声明。
- 语义标签 = 内容契约:
<article>承诺「我是完整独立内容」,<section>承诺「我是有主题的一组内容且通常带标题」。不能只想布局好看就乱用。 - main 唯一,header/footer 可多个:页面级 header/footer 各一个;但每个 article 内部还可以有自己的 header(文章标题区)和 footer(作者信息)。
- viewport 是移动端生命线:
width=device-width, initial-scale=1.0这串值背下来,几乎所有响应式页面都这么写。
你可能会懵的地方
-
section 和 div 到底什么区别? section 自带语义「这是文档的一个章节」,且规范建议内部带标题(h2-h6)。如果你只是想包一层做样式或 JS 钩子,用 div;如果内容能在大纲(outline)里独立成节,用 section。判断标准:给它起个标题,起得出来就是 section,起不出来就是 div。
-
article 和 section 谁套谁? 都可以。一篇长文(article)内部可以有多个 section(章节);一个 section(如「评论区」)里也可以有多个 article(每条评论独立完整)。看内容的独立性。
-
header 不就是页头吗? 不只是。
<header>表示「引导性内容的容器」,页面有一个页头 header,每个 article 里也可以有自己的 header 放标题和发布日期。footer 同理。 -
h1 一页只能有一个吗? HTML5 规范允许每个 sectioning 元素里各有 h1,但 SEO 实践和屏幕阅读器习惯仍推荐:全页一个 h1(页面主题),其余用 h2-h6 逐级递进,不要跳级(h1 直接到 h3)。
-
** aside 必须放右边吗?** 和位置无关。aside 表示「与主内容相关但可剥离的内容」,放左边、底部、甚至包在 article 内部都可以,位置是 CSS 的事。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 整页 div + class="header" | 无语义,SEO 和无障碍受损 | 用 <header>、<main> 等语义标签 |
两个 <main> 并列 | 违反规范,屏幕阅读器迷路 | 全页只留一个 main,其余用 div 或 section |
<section> 里没有标题 | section 语义不成立 | 加 h2-h6,或改用 div |
用 <br><br> 隔开区块 | 滥用换行做布局 | 块级元素天然分行,间距用 CSS margin |
viewport 写成 width=960 | 移动端页面被锁死宽度 | width=device-width, initial-scale=1.0 |
| charset 写在 title 之后 | 标题中文已按错误编码解析 | charset 永远是 head 第一个子元素 |
卡点急救
- 手机上页面整体缩小了一圈:缺 viewport meta,补上
<meta name="viewport" content="width=device-width, initial-scale=1.0">。 - 中文变成「æ–‡å—」:文件保存编码不是 UTF-8,或 charset 声明位置太后。VS Code 右下角点击编码 → Save with Encoding → UTF-8。
- 布局在 IE/老浏览器全塌:老浏览器不认识 HTML5 新标签,会当成行内元素。现代开发不用管 IE,但要知道历史上靠
display:blockCSS 修复。 - 不知道某标签用语义是否合适:查 MDN 该标签页面底部的「Technical summary」,里面写明了允许的父元素和内容类别。
面试常问
-
DOCTYPE 不写会怎样? 触发怪异模式(Quirks Mode):盒模型变成 IE5 式(width 含 padding 和 border)、表格字体不继承、行内元素垂直对齐异常。写
<!DOCTYPE html>进入标准模式。 -
语义化标签的好处? 三点:①SEO——爬虫优先索引 main/article 内容;②可访问性——屏幕阅读器靠地标跳转;③可维护性——结构自解释,减少 class 命名负担。
-
header 和 h1-h6 的 heading 是一回事吗? 不是。header 是容器标签(放引导内容),h1-h6 是标题文本标签。header 里通常含一个标题,但也能放 logo、搜索框、导航。
-
HTML5 废弃了哪些标签?
<font>、<center>、<big>、<frame>、<frameset>、<applet>等纯表现类标签全部废弃,表现交给 CSS。
自测三问
- 写出标准 head 必备的四个 meta/title 配置,并说明 viewport 每个值的含义。
- 一篇博客页面有「正文 + 作者卡 + 相关推荐 + 评论区」,分别该用什么语义标签?
- 为什么 charset 声明必须放在 head 的最前面?
小结一句话
文档结构是页面的地基:DOCTYPE 和 head 元数据决定浏览器怎么解析,语义化标签决定搜索引擎、屏幕阅读器和同事怎么理解你的内容。
延伸
- MDN:文档和网站结构
- 下一课:文本标签——标题、段落、强调、引用的正确用法。