本书第四版(英文原版),于 2017 年年中完稿。中文于 2019 年 4 月出版。
简介
1994 年,CSS 第一个提案发布。目标是提供一个简单的声明式样式语言。
1996 年年末,CSS1 制定完成。
CSS2 规范于 1998 年年初定案,后续修订版 CSS 2.1。
此后,CSS 规范被分拆分成多个模块各自发展,不再有能涵盖一切的“CSS3 规范”一说。学习 CSS 特性,要去不同的 CSS 的规范中学习。
元素
HTML 中的常用元素(element)包括 div、span、p、table、a 等。
置换和非置换元素
置换元素
置换元素(replaced element)的内容由外部资源决定。img 和 input 都在其列。
<img src="howdy.gif">
非置换元素
HTML 中的大多数元素都是非置换元素(noreplaced element),即元素内容由用户代理在元素生成的框中显示。
<span>hi there</span>
元素显示方式
除了按照置换和非置换元素角度划分元素,根据显示方式,元素又分为块级和行内两种基本类型。
块级元素
HTML 中最常见的块级元素是 div 和 p。默认自成一行,填满父元素内容区域的框。
行内元素
HTML 中最常见的块级元素是 span、a、strong 和 em。默认行内显示。
注意,在 HTML 中,块级元素不能出现在行内元素中。
<!-- √ 在不改变标记的前提下,可以如此设置显示方式 --><style>p {display:inline;} em {display:block;}</style><body><p>This is a paragraph with <em>an inline element</em> within it.</p></body><!-- × 调换嵌套关系,就是有问题的了:违背规则:块级元素不能出现在行内元素中--><em>This is a paragraph with <p>an inline element</p> within it.</em>
未知标记的默认 display 值是 inline。
把 CSS 应用到 HTML
如何在 HTML 文档中关联 CSS?
link 标签
link 标签作用:把其他文档跟当前文档关联起来。
引入外部样式表(external stylesheet)的方式如下:
<link rel="stylesheet" href="style.css">
这里的 rel 属性是“relation”(关系)的简称。
候选样式表(alternate stylesheet):
<!-- 如果浏览器支持的话 --><link rel="alternate stylesheet" href="style.css" title="Default">
样式表类型:
- 候选样式表,rel 属性值 “alternate stylesheet”,且有 title 属性(用于分组)。
- 永久样式表,rel 属性值 “stylesheet”,且无 title 属性。
- 首选样式表,rel 属性值 “stylesheet”,且有 title 属性。有多个首选样式表的,只会使用其中一个,规则不明。
style 元素
使用 style 元素直接在文档中使用样式表:
<style>...</style>
style 标签之间的样式称为文档样式表(document stylesheet)或嵌入式样式表(embedded stylesheet)。
@import 指令
@import 指令在 style 标签中使用,跟“link 标签”作用一样,都是用来加载外部样式表的。
<style>@import url(style.css); /* @import 放在开头 */h1 {color: gray;}</style>
@import 指令能够实现在一个样式表中引入另一个外部样式表的功能。
HTTP 链接
鲜为人知的一种方式。以 Apache 为例,修改 .htaccess 文件:
Header add link "</ui/testing.css>;rel=stylesheet;type=text/css"
行内样式
行内样式是通过 HTML 元素的 style 属性设置的:
<p style="color: gray;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed et est condimentum, interdum arcu id, lobortis nibh. </p>
除了 body 之外的标签(如 head 或 title),所有 HTML 标签都能设定 style 属性。
通常不建议使用 style 标签,除了 HTML,XML 中很少使用这个属性,不过提供了一定的灵活性。
样式表的内容
标记
样式表中不能出现标记。但由于历史原因,style 元素中可以有 HTML 注释(但我用浏览器测试,似乎这个注释标记会被忽略,已经不支持了)。
<style><!--@import url(style.css);h1 {color: gray;}--></style>
规则的结构
- 一个样式表由一系列规则(Rule)构成,
- 规则由两个基本部分构成:选择符(Selector)和声明块(Declaration block),
- 声明块由一个或多个声明(Declaration)组成,
- 一个声明包含属性(Property)和对应的值(Value)。

上图的规则,将 h1 元素设置为黄底红字。
厂商前缀
浏览器厂商通过厂商前缀(vendor prefix)标记实验性或专属的属性、值或其他内容。
常见的厂商前缀包括:
| Prefix | Vendor |
|---|---|
| -epub- | International Digital Publishing Forum ePub format |
| -moz- | Mozilla-based browsers (e.g., Firefox) |
| -ms- | Microsoft Internet Explorer |
| -o- | Opera-based browsers |
| -webkit- | Webkit-based browsers (e.g., safari and Chrome) |
厂商前缀出现的目的是为了浏览器厂商测试新特性,这么做既能保证兼容性,又不用担心与其它浏览器不兼容。
处理空白
CSS 对待空白的方式跟 HTML 差不多,连续的空白会被合并成一个空白。
CSS 注释
CSS 中,只能使用 /* */ 的方式添加注释,单行多行都可以;且 CSS 注释不能嵌套,否则是无效的。
媒体查询
媒体查询(Media query)定义浏览器在何种媒体环境中使用指定样式表。
用法
媒体查询可以在以下几个地方使用。
- link 元素的 media 属性
- style 元素的 media 属性
- @import 声明的媒体描述符部分
- @media 声明的媒体描述符部分
简单的媒体查询
看一个简单的例子:
h1 {color: maroon;}@media projection {body {background: yellow;}}
上面样式指定,在投影媒体中 body 有一个黄色背景。
媒体类型
媒体类型由 CSS2 引入。包括(但不限于):
- all:指定在所有媒体中应用,
- print:指定在打印和预览文档时应用,
- screen:指定在屏幕媒体上展示文档使用。桌面计算机上运行的所有 Web 浏览器都是屏幕媒体的用户代理。
当一个样式表要在多个媒体类型下使用时,使用逗号分隔媒体类型。
<link rel="stylesheet" href="style.css" media="screen, print"><style media="screen, print"></style>@import url(style.css) screen, print;@media screen, print {...}
媒体描述符
- 一个媒体描述符由一个媒体类型和一个或多个媒体特性列表构成。
- 其中,(媒体)特性描述符要放在圆括号中。
- 如果没有指定媒体类型,就是应用到所有媒体上。
/*下面两个示例是等效的 */@media all and (min-resolution: 96dpi) {...}@media (min-resolution: 96dpi) {...}
多个特性描述符使用 and 关键字连接,除此之外,还有 not 和 only 关键字:
- and:当连接的多个媒体同时满足条件,整个查询结果才为真。例如:(color) and (orientation: landscape) and (min-device-width: 800px),这表示当媒体环境是彩色、横放且屏幕宽至少 800px 像素,才会应用样式表。
- not:对整个查询取反。例如:not (color) and (orientation: landscape) and (min-device-width: 800px),这表示只要上述三个条件不同时满足,就会应用样式表。
**not**关键字只能在媒体查询的开头使用。 - only:表示只在满足媒体查询条件的浏览器中应用。与 not 一样,
**only**只能在媒体查询的开头使用。
媒体类型描述符和值的类型
截止到 2017 年:
| width | max-device-width | min-color-index |
|---|---|---|
| min-width | aspect-ratio | max-color-index |
| max-width | min-aspect-ratio | monochrome |
| device-width | max-aspect-ratio | min-monochrome |
| min-device-width | device-aspect-ratio | max-monochrome |
| max-device-width | min-device-aspect-ratio | resolution |
| height | max-device-aspect-ratio | min-resolution |
| min-height | color | max-resolution |
| max-height | min-color | orientation |
| device-height | max-color | scan |
| min-device-height | color-index | grid |
还有两种新增的值。
特性查询
特性查询(feature query)是指根据用户代理是否支持特定 CSS 属性及其值来应用一段样式,结构上跟媒体查询很像。
@supports (color: black) {body {color: black;}}
上面的意思是,“如果浏览器能识别并处理 color: black”这个声明,就应用这段样式(即将 body 的背景色设置成黑色),否则跳过这段样式。
使用特性查询,可以实现渐进增强样式。
@supports (display: grid) {#main {display: grid}}
上述样式,是在支持栅格布局的浏览器中应用。
特性查询还支持嵌套。
@supports (display: flex) {@media screen {/* 针对屏幕媒体的弹性盒样式 */}@media print {/* 针对印刷媒体的弹性盒样式 */}}
也可能在响应式媒体查询块中使用 @supports() 块:
@media screen and (max-width: 30em) {@supports (display: flex) {/* 针对小屏幕的弹性盒样式 */}}@media screen and (min-width: 30em) {@supports (display: flex) {/* 针对大屏幕的弹性盒样式 */}}
与媒体查询类似,特性查询也支持使用逻辑运算符 and:
@supports (display: flex) and (shape-outside: circle()) {/* 栅格和形状样式 */}/* 等价于 */@supports (display: flex) {@supports (shape-outside: circle()) {/* 栅格和形状样式 */}}
还有取反运算符 not:
@supports not (display: flex) {/* 不支持栅格时使用的样式 */}
特性查询时,既要写属性也要写值。举个例子,IE 4 就开始支持 display 属性了,但是不支持 flex 布局的。
/* × 这种测试肯定是不行的 */@supports (display) {/* 栅格样式 */}
小结
- CSS 简单一点,只使用 display 属性;复杂一点,则可以为文档关联样式表。
- 借助 @supports() 甚至可以使用纯 CSS 实现基本的渐进增强功能。
