本书第四版(英文原版),于 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 都在其列。

  1. <img src="howdy.gif">

非置换元素

HTML 中的大多数元素都是非置换元素(noreplaced element),即元素内容由用户代理在元素生成的框中显示。

  1. <span>hi there</span>

元素显示方式

除了按照置换和非置换元素角度划分元素,根据显示方式,元素又分为块级和行内两种基本类型。

块级元素

HTML 中最常见的块级元素是 div 和 p。默认自成一行,填满父元素内容区域的框。

行内元素

HTML 中最常见的块级元素是 span、a、strong 和 em。默认行内显示。

注意,在 HTML 中,块级元素不能出现在行内元素中。

  1. <!-- √ 在不改变标记的前提下,可以如此设置显示方式 -->
  2. <style>p {display:inline;} em {display:block;}</style>
  3. <body>
  4. <p>This is a paragraph with <em>an inline element</em> within it.</p>
  5. </body>
  6. <!-- × 调换嵌套关系,就是有问题的了:
  7. 违背规则:块级元素不能出现在行内元素中
  8. -->
  9. <em>This is a paragraph with <p>an inline element</p> within it.</em>

未知标记的默认 display 值是 inline。

把 CSS 应用到 HTML

如何在 HTML 文档中关联 CSS?

link 标签

link 标签作用:把其他文档跟当前文档关联起来。

引入外部样式表(external stylesheet)的方式如下:

  1. <link rel="stylesheet" href="style.css">

这里的 rel 属性是“relation”(关系)的简称。

候选样式表(alternate stylesheet):

  1. <!-- 如果浏览器支持的话 -->
  2. <link rel="alternate stylesheet" href="style.css" title="Default">

样式表类型:

  1. 候选样式表,rel 属性值 “alternate stylesheet”,且有 title 属性(用于分组)。
  2. 永久样式表,rel 属性值 “stylesheet”,且无 title 属性。
  3. 首选样式表,rel 属性值 “stylesheet”,且有 title 属性。有多个首选样式表的,只会使用其中一个,规则不明。

style 元素

使用 style 元素直接在文档中使用样式表:

  1. <style>...</style>

style 标签之间的样式称为文档样式表(document stylesheet)或嵌入式样式表(embedded stylesheet)。

@import 指令

@import 指令在 style 标签中使用,跟“link 标签”作用一样,都是用来加载外部样式表的。

  1. <style>
  2. @import url(style.css); /* @import 放在开头 */
  3. h1 {color: gray;}
  4. </style>

@import 指令能够实现在一个样式表中引入另一个外部样式表的功能。

HTTP 链接

鲜为人知的一种方式。以 Apache 为例,修改 .htaccess 文件:

  1. Header add link "</ui/testing.css>;rel=stylesheet;type=text/css"

行内样式

行内样式是通过 HTML 元素的 style 属性设置的:

  1. <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 注释(但我用浏览器测试,似乎这个注释标记会被忽略,已经不支持了)。

  1. <style><!--
  2. @import url(style.css);
  3. h1 {color: gray;}
  4. --></style>

规则的结构

  • 一个样式表由一系列规则(Rule)构成,
  • 规则由两个基本部分构成:选择符(Selector)和声明块(Declaration block),
  • 声明块由一个或多个声明(Declaration)组成,
  • 一个声明包含属性(Property)和对应的值(Value)。

《CSS 权威指南》:CSS和文档 - 图1

上图的规则,将 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 声明的媒体描述符部分

简单的媒体查询

看一个简单的例子:

  1. h1 {color: maroon;}
  2. @media projection {
  3. body {background: yellow;}
  4. }

上面样式指定,在投影媒体中 body 有一个黄色背景。

媒体类型

媒体类型由 CSS2 引入。包括(但不限于):

  • all:指定在所有媒体中应用,
  • print:指定在打印和预览文档时应用,
  • screen:指定在屏幕媒体上展示文档使用。桌面计算机上运行的所有 Web 浏览器都是屏幕媒体的用户代理。

当一个样式表要在多个媒体类型下使用时,使用逗号分隔媒体类型。

  1. <link rel="stylesheet" href="style.css" media="screen, print">
  2. <style media="screen, print"></style>
  3. @import url(style.css) screen, print;
  4. @media screen, print {...}

媒体描述符

  • 一个媒体描述符由一个媒体类型和一个或多个媒体特性列表构成。
  • 其中,(媒体)特性描述符要放在圆括号中
  • 如果没有指定媒体类型,就是应用到所有媒体上。
  1. /*下面两个示例是等效的 */
  2. @media all and (min-resolution: 96dpi) {...}
  3. @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 属性及其值来应用一段样式,结构上跟媒体查询很像。

  1. @supports (color: black) {
  2. body {color: black;}
  3. }

上面的意思是,“如果浏览器能识别并处理 color: black”这个声明,就应用这段样式(即将 body 的背景色设置成黑色),否则跳过这段样式。

使用特性查询,可以实现渐进增强样式。

  1. @supports (display: grid) {
  2. #main {display: grid}
  3. }

上述样式,是在支持栅格布局的浏览器中应用。

特性查询还支持嵌套。

  1. @supports (display: flex) {
  2. @media screen {
  3. /* 针对屏幕媒体的弹性盒样式 */
  4. }
  5. @media print {
  6. /* 针对印刷媒体的弹性盒样式 */
  7. }
  8. }

也可能在响应式媒体查询块中使用 @supports() 块:

  1. @media screen and (max-width: 30em) {
  2. @supports (display: flex) {
  3. /* 针对小屏幕的弹性盒样式 */
  4. }
  5. }
  6. @media screen and (min-width: 30em) {
  7. @supports (display: flex) {
  8. /* 针对大屏幕的弹性盒样式 */
  9. }
  10. }

与媒体查询类似,特性查询也支持使用逻辑运算符 and:

  1. @supports (display: flex) and (shape-outside: circle()) {
  2. /* 栅格和形状样式 */
  3. }
  4. /* 等价于 */
  5. @supports (display: flex) {
  6. @supports (shape-outside: circle()) {
  7. /* 栅格和形状样式 */
  8. }
  9. }

还有取反运算符 not:

  1. @supports not (display: flex) {
  2. /* 不支持栅格时使用的样式 */
  3. }

特性查询时,既要写属性也要写值。举个例子,IE 4 就开始支持 display 属性了,但是不支持 flex 布局的。

  1. /* × 这种测试肯定是不行的 */
  2. @supports (display) {
  3. /* 栅格样式 */
  4. }

小结

  • CSS 简单一点,只使用 display 属性;复杂一点,则可以为文档关联样式表。
  • 借助 @supports() 甚至可以使用纯 CSS 实现基本的渐进增强功能。