本节摘要:CSS(层叠样式表)是负责网页视觉呈现的语言,它把"长什么样"从 HTML 结构中抽离出来集中管理。本节从 CSS 的诞生背景讲起,动手比较内联、内部、外部三种引入方式的优劣,最后用一个完整的小页面把语法规则跑通。
完成本节后,你将能够:解释 CSS 是什么以及它解决了什么问题;区分内联、内部和外部三种引入方式并选择最合适的方案;编写符合规范的基本 CSS 规则;用浏览器的"查看源代码 + 开发者工具"验证样式是否生效。
CSS 的全称是 Cascading Style Sheets(层叠样式表)。这个名字包含三个关键词,每一个都指向 CSS 的一项核心能力。
**Cascading(层叠)**指的是多条规则可以同时作用于同一个元素,浏览器通过一套明确的优先级规则来决定最终生效的样式。你在基础样式文件里写了链接的颜色,又在组件样式里覆盖了它——两个"老板"同时下命令,浏览器靠层叠规则裁定谁说了算。这个"层叠"机制是 CSS 能够管理复杂页面样式的根基,第 2 章会专门拆解它。
**Style(样式)**说明 CSS 的职责范围:颜色、字体、间距、尺寸、位置、动画——所有与"看起来怎么样"有关的事情,都归 CSS 管。它不负责内容是什么(HTML 管),也不负责行为逻辑(JavaScript 管)。三权分立,各司其职。
**Sheets(表)**暗示了 CSS 的组织方式:样式以规则表的形式存在,每条规则把"选择器"和"声明"对应起来,形成一张从元素到样式的映射表。你在 CSS 文件里写的不是程序流程,而是一张一张的"样式登记表"。
在 CSS 出现之前(1996 年以前),HTML 标签本身就携带着样式信息——<font color="red"> 这样的写法随处可见,甚至有人用表格标签排版整个页面。这导致结构和样式纠缠在一起,修改一个按钮的颜色需要在几十个页面里逐个替换。CSS 的诞生就是为了解决这个痛点:把样式从 HTML 中抽离出来,集中管理。
CSS 从 1996 年至今的演进历程
这条时间线值得看一眼,因为它解释了今天 CSS 的"分层现状":CSS2 时代的定位(position)和浮动(float)至今仍在使用;CSS3 时代的 Flexbox 和 Grid 是现代布局的主力;2023 年前后的新特性(容器查询、原生嵌套)正在逐步普及。本教程的布局章节正是按这个演进脉络组织的——你会先学老技术(理解原理、维护旧代码),再学新技术(日常主力)。
把 CSS 引入 HTML 页面有三种方式,它们各有适用场景。理解这三者的区别,是写出可维护样式代码的前提。下面每种方式都给出可以直接运行的代码,建议逐一动手试一遍——比较过真实效果,记忆才牢固。
直接在 HTML 标签的 style 属性中写样式。这是最直接的方式,但也是最不推荐的方式。
<p style="color: red; font-size: 16px;">这段文字是红色的</p>
内联样式的优先级很高(第 2 章会详细讲优先级),但它把样式和结构混在一起,违反了 CSS 的设计初衷。想象一下,如果你有 50 个段落需要改颜色,逐个修改 style 属性会是一场灾难。内联样式合理的用途很窄:在 JavaScript 中动态设置样式,或者编写邮件模板(因为很多邮件客户端会剥离 <style> 标签和外部文件,只认内联)。
在 HTML 文档的 <head> 中用 <style> 标签包裹 CSS 代码。这种方式适合单个页面的特殊样式。
<head> <style> p { color: blue; line-height: 1.6; } .highlight { background-color: yellow; } </style> </head>
内部样式比内联样式好一些——至少样式和结构分离了,但它仍然绑定在特定的 HTML 文件中。如果网站有 20 个页面都需要相同的段落样式,你就需要在每个页面的 <head> 里复制一遍这段代码,改一次样式就要改 20 个文件。它适合做"只属于这一个页面"的样式,比如某个活动页的专属效果。
创建一个独立的 .css 文件,然后在 HTML 中用 <link> 标签引入。这是实际项目中的标准做法。
/* styles.css — 独立的样式文件 */ p { color: blue; line-height: 1.6; } .highlight { background-color: yellow; }
<head> <link rel="stylesheet" href="styles.css"> </head>
外部样式表的优势一目了然:一个 CSS 文件可以同时服务于网站的所有页面。修改一处,全站生效。浏览器还会缓存 CSS 文件,用户访问第二个页面时不需要重新下载样式——既省流量又加快渲染。此外还有 @import 引入方式,它在样式文件内部引入另一个样式文件,但因为串行加载会影响性能,实际项目中已很少推荐。
| 引入方式 | 语法位置 | 复用性 | 优先级 | 推荐场景 |
|---|---|---|---|---|
| 内联 | style 属性 |
不可复用 | 最高 | JS 动态修改、邮件模板 |
| 内部 | <style> 标签 |
仅当前页 | 中等 | 单页特殊样式 |
| 外部 | <link> 引入 |
全站复用 | 正常 | 所有正式项目 |
一条 CSS 规则由两部分组成:选择器和声明块。
选择器 { 属性: 值; 属性: 值; }
选择器告诉浏览器"要修饰哪些元素",声明块告诉浏览器"怎么修饰"。声明块由花括号包裹,内部每条声明包含一个属性名、一个冒号和一个值,最后以分号结尾。
来看一个完整的例子:
/* 选中所有 class 包含 title 的元素 */ .title { font-size: 24px; /* 字号 24 像素 */ color: #333333; /* 深灰色文字 */ margin-bottom: 16px; /* 下方留 16 像素间距 */ font-weight: bold; /* 加粗 */ }
这里有几个语法细节值得注意。属性名是 CSS 预定义的关键词,不能自己发明——你不能写 text-size,因为 CSS 不认识这个属性,正确的写法是 font-size。写错的属性不会报错,浏览器只是静默忽略整条声明,这也是"样式不生效"时最容易漏查的原因。属性值后面必须跟分号,虽然最后一条声明的分号可以省略,但强烈建议始终写上,这样后续添加新属性时不会因为忘补分号而让前一行失效。
注释用 /* */ 包裹,可以跨行。CSS 没有单行注释语法(// 在标准 CSS 中无效),这是一个常见的初学者陷阱——写了 // 之后,后面的所有规则都可能被浏览器丢弃。
语法之外还有一条书写规范值得从一开始就养成:一条声明一行,属性名后一个空格,选择器与花括号之间一个空格。这些细节不影响运行,但直接影响代码的可读性,也影响别人 review 你代码时的第一印象。
把上面的知识组合起来,写一个完整的 HTML 页面,用外部样式表控制样式。跟着做:新建一个文件夹,创建下面两个文件放进去,用浏览器打开 HTML 文件。
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>我的第一个 CSS 页面</title> <link rel="stylesheet" href="style.css"> </head> <body> <header> <h1 class="title">欢迎来到 CSS 的世界</h1> </header> <main> <p>这是一段普通的文字。</p> <p class="highlight">这段文字会被高亮显示。</p> </main> </body> </html>
/* style.css */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: "Microsoft YaHei", sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; } .title { font-size: 28px; color: #1565C0; border-bottom: 2px solid #1565C0; padding-bottom: 8px; margin-bottom: 20px; } p { margin-bottom: 12px; } .highlight { background-color: #FFF9C4; padding: 8px 12px; border-left: 4px solid #FBC02D; }
保存后用浏览器打开 HTML 文件,你会看到:标题是蓝色的,底部有一条蓝色下划线;整个内容区最宽 800 像素并在窗口中水平居中;高亮段落有浅黄色背景和左侧的黄色竖线。逐行对照代码和效果——max-width 和 margin: 0 auto 负责居中,border-left 画出了那条竖线。这个"对照"动作本身就是学习:眼睛看到的效果必须能在代码里找到责任人。
再做三个实验巩固理解。实验一:把 style.css 里 body 的 max-width 改成 400px,刷新后内容区变窄——你刚刚完成了第一次响应式调整。实验二:删掉 HTML 里的 <link> 标签,刷新后页面回到浏览器默认样式——这证明了样式的确来自外部文件。实验三:给第二个 <p> 加上 style="background-color: pink",刷新后它变成粉色,覆盖了 .highlight 的黄色——你提前见识了内联样式的最高优先级。
了解一点渲染流程,很多"反直觉现象"就变得合理。浏览器拿到 HTML 后会解析成 DOM 树,同时解析 CSS 生成 CSSOM(CSS 对象模型);两者合并成一棵渲染树,计算每个元素的几何信息(布局),最后绘制成像素。关键推论有三个:其一,<link> 放在 <head> 里是为了让浏览器尽早开始下载 CSS,避免"先裸奔再穿衣服"的闪烁;其二,写错的属性和选择器在解析阶段被静默丢弃,不会中断后续规则;其三,最终每个元素的每条属性只有一个赢家——由层叠、优先级和继承共同决定,这正是第 2 章的主题。
💡 动手建议:把上面两个文件的代码复制到你的编辑器里,保存后用浏览器打开。然后尝试修改样式文件中的颜色值——比如把
#1565C0改成#C62828,保存后刷新浏览器,观察变化。这种"改一行看一次效果"的方式是学习 CSS 最快的途径,本教程后续每一节都建立在这个循环上。
⚠️ 编码提醒:HTML 文件中的
<meta charset="UTF-8">不可省略。没有它,浏览器可能用错误的编码解析中文内容,导致乱码。CSS 文件本身也应该保存为 UTF-8 编码(大多数现代编辑器默认就是)。

图:一条 CSS 规则的结构解剖
问:为什么我的样式改了却没生效? 按四个方向排查:一查文件有没有真正引入——打开开发者工具的 Network 面板看样式文件的请求状态,路径写错时这里是红色;二查选择器是否命中——Styles 面板里看不到你的规则,说明选择器没匹配上;三查属性拼写——静默失败不报错;四查是否被覆盖——规则在但属性被划掉了,那是层叠的裁决,答案在第二章末节。
问:一个页面能引入多少个样式文件? 数量没有限制,但每个文件都是一次独立的网络请求。现代工程实践通常在构建阶段把多个文件合并成少数几个,开发时按模块分文件维护、上线时合并加载,兼顾可读性与性能。学习阶段不必纠结这个,两三个文件分工清晰就够用。
问:样式文件放 head 里还是 body 末尾? 样式放 head。浏览器解析到样式链接会先加载再渲染后续内容,避免页面出现"先裸奔再穿衣服"的闪烁。这和脚本文件的习惯正好相反——脚本常放 body 末尾或加延迟加载,因为脚本是执行逻辑,晚点执行通常无妨。
style 属性、内部用 <style> 标签、外部用 <link> 引入独立文件;正式项目一律首选外部样式表。/* */,没有 //。<head> 中尽早加载;每个属性最终只有一个值生效。下一节我们把镜头对准声明中的"值"——颜色怎么表示、单位怎么选,这些词汇将贯穿全教程。