HTML 文档结构
这一课你将能做到
- 手写一个符合 HTML5 标准的完整页面骨架,不遗漏任何必要元素
- 正确理解
<head> 与 <body> 的分工,合理放置元数据、资源和可见内容
- 在页面中正确引入 CSS 和 JavaScript,并知道
defer、async、media 等属性的作用
为什么要学
如果把网页比作一封信,HTML 文档结构就是信封格式和信纸规范——没有它,邮递员(浏览器)不知道谁是收信人、信里用什么语言、该按什么顺序阅读。一个标准、完整的文档结构是 SEO(搜索引擎优化)、无障碍访问、社交分享预览和跨设备兼容的基础。
CodeForge 的课程详情页需要在 <head> 中声明字符编码、视口设置、页面标题和描述,这样搜索引擎才能正确索引,微信分享时才能显示卡片预览。省略这些元数据,页面可能在手机上被错误缩放,或被搜索引擎降低排名。
先建立图像
<!DOCTYPE html>
<html lang="zh-CN">
├── <head> ← 元数据:给浏览器和搜索引擎看的「说明书封面」
│ ├── charset ← 字符编码(UTF-8 是标配)
│ ├── viewport ← 视口设置(移动端必须)
│ ├── title ← 浏览器标签页标题、搜索引擎结果标题
│ ├── meta desc ← 搜索引擎结果描述
│ ├── link css ← 外部样式表
│ └── script ← 外部脚本(可放 head 或 body 底部)
│
└── <body> ← 可见内容:用户实际看到的所有东西
├── header
├── nav
├── main
└── footer
跟着做
步骤 1:写出标准 HTML5 骨架
创建 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="CodeForge 前端基础课程,系统学习 HTML5、CSS3 与现代布局技术。">
<title>课程详情 | CodeForge 学习平台</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<h1>HTML/CSS 基础精讲</h1>
</header>
<main>
<p>本课程涵盖现代网页开发所需的全部基础技能。</p>
</main>
<footer>
<p>© 2026 CodeForge</p>
</footer>
<script src="app.js" defer></script>
</body>
</html>
逐行验证:文件开头必须是 <!DOCTYPE html>;<html> 标签要加 lang="zh-CN";<meta charset="UTF-8"> 必须是 <head> 中的第一行;<title> 不可省略。
步骤 2:添加 Open Graph 社交分享元数据
在 <head> 中追加以下标签,让分享链接时显示卡片:
<meta property="og:title" content="HTML/CSS 基础精讲 | CodeForge">
<meta property="og:description" content="系统学习 HTML5、CSS3、Flexbox、Grid 与响应式设计。">
<meta property="og:type" content="website">
<meta property="og:image" content="https://codeforge.example.com/og-cover.png">
微信、钉钉、Slack 等应用抓取网页分享卡片时,读取的就是这些 og:* 元数据。
步骤 3:引入 CSS 的三种方式对比
编辑 structure.html,在 <head> 中尝试三种方式:
<!-- 方式 1:外部样式表(推荐,可缓存、可复用) -->
<link rel="stylesheet" href="styles.css">
<!-- 方式 2:内部样式表(仅当前页使用,或做 Demo) -->
<style>
body { font-family: system-ui, sans-serif; }
</style>
<!-- 方式 3:行内样式(优先级最高,但难以维护,仅用于动态计算值) -->
<p style="color: #2563eb;">这段文字是蓝色的</p>
生产环境优先使用外部样式表;内部样式适合单页原型或性能关键的临界 CSS;行内样式尽量避免,除非值由 JavaScript 动态计算。
步骤 4:引入 JavaScript 的位置与加载策略
<!-- 放在 <head> 中,阻塞解析,直到脚本下载并执行完毕 -->
<script src="app.js"></script>
<!-- 放在 <head> 中,异步下载,下载完成后立即执行(不保证顺序) -->
<script src="analytics.js" async></script>
<!-- 放在 <head> 中,异步下载,延迟到 HTML 解析完成后按顺序执行(最常用) -->
<script src="app.js" defer></script>
<!-- 放在 </body> 前,等 HTML 解析完再下载执行(传统做法,效果类似 defer) -->
<body>
<!-- 页面内容 -->
<script src="app.js"></script>
</body>
现代推荐做法:<script src="..." defer></script> 放在 <head> 中。既不会阻塞 HTML 解析,又能保证脚本在 DOM 就绪后按声明顺序执行。
步骤 5:设置视口与主题色
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#0f172a">
viewport 让移动端浏览器以正确宽度渲染页面,禁止自动缩小。theme-color 让 Chrome Android 的地址栏和 iOS Safari 的顶部状态栏匹配网站主题色。
讲清楚要点
-
<!DOCTYPE html> 不可省略:它告诉浏览器使用「标准模式」渲染。如果省略,浏览器会进入「怪异模式」(Quirks Mode),盒模型计算、边距处理等会出现历史兼容性偏差,导致不同浏览器表现不一致。
-
<html lang="zh-CN"> 影响深远:屏幕阅读器用它决定发音规则,搜索引擎用它判断目标受众,浏览器的翻译功能也依赖它。多语言站点应根据当前页面内容动态切换,如 lang="en-US"。
-
<meta charset="UTF-8"> 必须放在 <head> 最前面:浏览器读到这行之前,默认用 ASCII 或系统编码解析。如果前面有注释或其他标签,中文可能已经开始乱码。理想位置是 <head> 下的第一个子元素。
-
<title> 不仅是标签页标题:它是搜索引擎结果页(SERP)的默认标题,也是浏览器书签的默认名称。每个页面应有唯一、描述准确的标题,格式建议「页面内容 | 站点名称」。
-
CSS 引入优先级:行内样式 > 内部 <style> > 外部样式表。同名属性后面的覆盖前面的(如果选择器权重相同)。理解层叠顺序是调试样式冲突的基础。
-
defer vs async:defer 保证脚本按 HTML 中出现的顺序执行,且都在 DOM 解析完成后执行,适合有依赖关系的业务脚本。async 下载完后立即执行,不保证顺序,适合独立运行的统计代码、广告脚本。
你可能会懵的地方
-
<!DOCTYPE html> 后面为什么没有版本号?
HTML5 的 DOCTYPE 是故意设计得这么简洁的。历史上的 HTML 4.01 和 XHTML 1.0 需要写很长的 DTD 引用,容易出错。HTML5 用这一行就覆盖了所有标准模式需求。
-
<head> 里的内容用户看不到,那它重要吗?
非常重要。<meta charset> 决定中文能否正常显示;<meta viewport> 决定手机上的缩放行为;<meta description> 影响搜索引擎摘要;<link rel="stylesheet"> 决定样式。这些虽然不可见,却直接影响用户体验和流量。
-
为什么要把 CSS 放 <head>,JS 放底部或用 defer?
CSS 会阻塞渲染(浏览器需要知道样式才能画出页面),所以要尽早加载。JS 会阻塞 HTML 解析(因为脚本可能修改 DOM),所以推迟执行可以让页面内容更快呈现给用户。
-
src 和 href 有什么区别?
href(Hypertext Reference)用于链接外部资源,浏览器遇到 <link href="..."> 时会并行下载,不阻塞当前文档处理。src(Source)用于嵌入资源,如 <script src="...">、<img src="...">,浏览器会暂停解析去下载并执行/渲染该资源。
-
可以同时写 <script> 和 <script defer> 吗?
可以,但普通 <script> 会阻塞解析,而 defer 脚本不会。如果普通脚本在 defer 脚本前面,它会先执行;defer 脚本则统一推迟到 HTML 解析结束后、DOMContentLoaded 事件前按顺序执行。
错法对照
| 错法 | 问题 | 正解 |
|---|
省略 <!DOCTYPE html> | 触发怪异模式,盒模型计算出错 | 始终作为文件第一行 |
<meta charset> 放在 <title> 之后 | 浏览器解析 title 时已用错误编码 | charset 必须是 head 的第一个子元素 |
多个页面使用相同的 <title> | SEO 降权,用户无法在标签页区分 | 每个页面使用唯一标题 |
用 <script src> 在 <head> 中加载大量脚本 | 阻塞首屏渲染,页面白屏时间长 | 使用 defer 或放在 </body> 前 |
省略 lang 属性 | 屏幕阅读器发音错误,搜索引擎语言判断失败 | <html lang="zh-CN"> |
用 <meta http-equiv="refresh"> 做跳转 | 破坏后退按钮行为,不利于 SEO | 使用服务器端 301/302 重定向 |
卡点急救
-
页面在手机上看被缩小了,文字很小:检查是否有 <meta name="viewport" content="width=device-width, initial-scale=1.0">。没有这行,移动端浏览器会假设页面宽度为 980px 并整体缩小。
-
CSS 文件加载了但没有效果:按 F12 → Network 面板 → 找到 CSS 文件,看状态码是否是 200。如果是 404,检查 href 路径是否正确(相对路径基于 HTML 文件所在目录)。
-
JS 报错 "Cannot read properties of null":脚本在 DOM 元素还没解析到时就开始执行。解决方案:把 <script> 移到 </body> 前,或加上 defer 属性,或把代码包在 document.addEventListener('DOMContentLoaded', ...) 中。
面试常问
-
「DOCTYPE 的作用是什么?不写会怎样?」
DOCTYPE 声明位于文档最前面,告知浏览器使用标准模式(Standards Mode)渲染文档。如果不写,浏览器会进入怪异模式(Quirks Mode),为了兼容早期网站,会使用非标准的盒模型和布局规则,导致页面在不同浏览器中表现不一致。
-
「<script> 标签中 defer 和 async 的区别?」
两者都不会阻塞 HTML 解析。async 在脚本下载完成后立即执行,不保证执行顺序,适合无依赖的独立脚本。defer 在 HTML 完全解析后、DOMContentLoaded 事件前按顺序执行,适合有依赖关系的业务脚本。现代项目推荐 defer。
-
「meta viewport 的原理是什么?」
移动端浏览器默认把网页放在一个叫「布局视口」(layout viewport)的虚拟画布上,宽度通常为 980px,然后缩小到屏幕大小。width=device-width 让布局视口宽度等于设备物理宽度,initial-scale=1.0 设置初始缩放比例为 1,从而确保 CSS 像素与设备独立像素 1:1 对应,页面以正确尺寸渲染。
自测三问
- 一个符合 HTML5 标准的页面,
<head> 中至少应包含哪三个标签?它们各自的作用是什么?
- 外部 CSS 应该用什么标签引入?外部 JS 应该用什么标签引入?为什么 JS 推荐加
defer?
- 如果你发现页面在手机上显示时整体被缩小,应该检查哪个 meta 标签?
小结一句话
HTML5 文档结构是网页的「宪法」——<!DOCTYPE html> 开启标准模式,<head> 承载元数据与资源引用,<body> 承载可见内容;理解各元素的职责和加载顺序,是写出健壮、可维护页面的前提。
延伸