├── .gitignore ├── README.md ├── _config.yml ├── book.json └── docs ├── 1_CSS_and_Documents ├── README.md ├── figure1.png ├── figure2.png ├── figure3.png ├── figure4.png ├── figure5.png ├── figure6.png ├── figure7.png └── web-yang-shi-li-shi-jian-jie.md ├── 2_Selectors ├── README.md ├── figure1-1.png ├── figure1-10.png ├── figure1-11.png ├── figure1-12.png ├── figure1-13.png ├── figure1-14.png ├── figure1-15.png ├── figure1-16.png ├── figure1-17.png ├── figure1-18.png ├── figure1-19.png ├── figure1-2.png ├── figure1-20.png ├── figure1-21.png ├── figure1-22.png ├── figure1-23.png ├── figure1-24.png ├── figure1-25.png ├── figure1-26.png ├── figure1-27.png ├── figure1-28.png ├── figure1-29.png ├── figure1-3.png ├── figure1-30.png ├── figure1-31.png ├── figure1-32.png ├── figure1-33.png ├── figure1-34.png ├── figure1-35.png ├── figure1-4.png ├── figure1-5.png ├── figure1-6.png ├── figure1-7.png ├── figure1-8.png └── figure1-9.png ├── 3_Specificity_and_the_Cascade └── README.md ├── 4_Values_and_Units └── README.md ├── 5_Fonts └── README.md ├── 6_Text ├── 1.png ├── 2.png └── README.md ├── 7_Basic_Visual_Format ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png └── README.md ├── README.md └── SUMMARY.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSS权威指南(第四版) 2 | 3 | 《CSS权威指南(CSS: The Definitive Guide)》是**Eric A. Meyer**所著,第三版发布于2006年。从2012年开始,CSS权威指南的第四版开始以分章节的形式由**O'Reilly**发行,目前已经发布了十章。 4 | 5 | 《CSS权威指南(第四版)》的第一章《CSS and Documents》在O'Reilly上是免费提供的,其它章节则不是。因此,这里将提供第一章的完整翻译,其后的章节则以重点总结和摘要翻译的形式提供。 6 | 7 | 如果您喜欢本书内容,请至[此处](http://www.oreilly.com/pub/au/52)购买英文原版,期待第四版尽快发行完整版并有国内出版商引入中文版。 8 | 9 | CSS的标准更新非常快,本书的第一章写于2012年,现在来看有些内容已经略有落后,而等到第四版的中文版引入国内时,又不知何年何月了。 10 | 11 | 12 | [全部章节](https://jack-sparrow.github.io/CSS-The-Definitive-Guide-4th-zh-CN/) 13 | 14 | [1 CSS和文档](https://jack-sparrow.github.io/CSS-The-Definitive-Guide-4th-zh-CN/docs/1_CSS_and_Documents/) 15 | 16 | [2 选择器](https://jack-sparrow.github.io/CSS-The-Definitive-Guide-4th-zh-CN/docs/2_Selectors/) 17 | 18 | [3 特度和层叠](https://jack-sparrow.github.io/CSS-The-Definitive-Guide-4th-zh-CN/docs/3_Specificity_and_the_Cascade/) 19 | 20 | [4 值和单位](https://jack-sparrow.github.io/CSS-The-Definitive-Guide-4th-zh-CN/docs/4_Values_and_Units/) 21 | 22 | [5 字体](https://jack-sparrow.github.io/CSS-The-Definitive-Guide-4th-zh-CN/docs/5_Fonts/) 23 | 24 | [6 文本](https://jack-sparrow.github.io/CSS-The-Definitive-Guide-4th-zh-CN/docs/6_Text/) 25 | 26 | [7 基本视觉格式化](https://jack-sparrow.github.io/CSS-The-Definitive-Guide-4th-zh-CN/docs/7_Basic_Visual_Format/) 27 | 28 | 29 | ### Update: 30 | 31 | 英文正式版已于 2017 年 10 月正式出版:[O'Reilly 官网](http://shop.oreilly.com/product/0636920012726.do) 32 | 33 | 亚马逊中国已经有售。 34 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": "./docs" 3 | } 4 | -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/README.md: -------------------------------------------------------------------------------- 1 | # CSS 和文档 2 | 3 | Cascading Style Sheets (CSS) 是一个能够变换文档和文档集合呈现方式的强大工具,它几乎已经扩展到 web 的每个角落,包括许多看起来不是 web 环境的地方。例如,基于 Gecko[1](#f1) 的浏览器通过 CSS 影响自身 chrome[1.1](#f1_1) 的呈现,许多 RSS 客户端允许你将 CSS 应用于推送内容,一些即时通讯客户端使用 CSS 来变换聊天窗口。JavaScript 框架(如 jQuery )甚至 JavaScript 本身所使用的语法中,都有 CSS 的踪迹。它无处不在! 4 | 5 | ## Web 样式简史 6 | 7 | CSS 首次提出于 1994 年,正当网络开始真正流行的时候。当时,浏览器赋予用户各种样式化能力——例如,在Mosaic[2](#f2)的显示偏好中,允许用户基于每个元素定义所有风格的字体系列、尺寸和颜色。而文档开发者却无法做到这些,他们所能做的只是把一段内容标记为段落、作为某级标题、作为预定义格式的文本或者其它很少量的元素类型中的一个。如果用户配置自己的浏览器,把所有一级标题设置成“微小”和粉色,而把六级标题设置为“巨大”和红色,那浏览器就会如用户所设置的显示。 8 | 9 | CSS就是在这种背景下引入的,目的是提供一种简单的、声明式的样式语言供文档开发者自由地使用,更重要的是,为开发者和用户提供同样的样式化能力。通过“层叠( cascade )”的手段,这些样式可以组合并按优先级排序,让开发者和阅读者都有对样式的控制权——尽管阅读者总是有最终的控制权。 10 | 11 | 工作迅速推进,到 1996 年年底 CSS1 标准完成了。新成立的 CSS 工作组继续向前推进 CSS2,浏览器们则在尽力以相互兼容的方式实现 CSS1。尽管每个单独的 CSS 片段都相当简单,但它们的组合却产生了令人意外的复杂行为。早期的实现还存在一些不幸的失误,比如今天已经臭名昭著的盒模型实现的差异。这些问题使 CSS 面临被完全摧毁的风险,但幸运的是一些聪明的提案被实现了,浏览器们也开始协调起来了。几年内,得益于持续增加的互通性和高关注度的开发者(如基于 CSS 重新设计的《连线(Wired)》杂志和 CSS 禅意花园(Zen Garden)),CSS 开始流行起来。 12 | 13 | 在这一切发生之前,CSS 工作组已经在 1998 年初完成了 CSS2 规范。CSS 2一完成,CSS3(以及一个 CSS2 的清晰化版本叫作 CSS2.1)的工作就立即开始了。与时俱进的 CSS3 被构造为一系列(理论上的)独立模块,而不是单个的整体规范。这种做法体现了当时活跃的 XHML 规范的影响,它(XHML)也因为类似的原因被拆分成模块。 14 | 15 | 把 CSS3 模块化的理由是,每个模块可以按照自己的步调发展,特别重要(或流行)的模块可以随着 W3C 的路线先行推进,而不必被其它模块拖延。事实也正是如此。到 2012 年初,3 个 CSS3 模块(与 CSS1 和 CSS 2.1 一起)达成了**完整推荐状态**[3](#f3)——CSS Color Level 3、CSS Namespaces 和 Selectors Level 3。与此同时,七个模块正处于**候选推荐状态**[4](#f4),其它几十个模块处在工作草案的不同阶段。按照以前的做法,颜色、选择器和命名空间三个模块将不得不等待规范中的所有其它模块都被完成或取消,才能作为完整规范的一部分被提案。得益于模块化,它们不需要等待规范的其它部分了。 16 | 17 | 模块化带来了好处,但也使得我们很难说有一个“CSS3 规范”存在。事实上并没有,而且也不会有这样一个规范。即便其它每个 CSS3 模块都达成了 level 3 ——假如,在2016年底(并没有)——可能那时已经有一个 Selectors Level 4 正在推进中了,我们应该把它叫做 CSS4 吗?其它“CSS3”里还在进行中的特性叫作什么呢?更别说还有 Grid Layout 这种连 Level 1 都没有达成的(模块)。 18 | 19 | 所以,虽然我们不能指着一个大部头说:“这就是 CSS3”,但我们可以对每个模块名称及它们所指代的功能特性进行讨论。模块灵活性上的好处远远大于它们引入的语义上尴尬的坏处。(如果你真的想要一个接近于整个的规范的东西,CSS 工作组每年都会发布年度“快照(Snapshot)”文档。) 20 | 21 | 进行到这里,我们可以开始理解 CSS 了。首先,从(文档)标记开始。 22 | 23 | ## 元素 24 | 25 | 元素是文档结构的基础。在 HTML 中,最常见的那些元素都很容易识别,例如`p`、`table`、`span`、`a`和`div`。每个元素都在文档展示中扮演各自的角色。 26 | 27 | ### 替换元素和非替换元素 28 | 29 | 虽然 CSS 依赖于元素,但并不是所有元素都一样。例如,图片和段落就不是同类型的元素,`span`和`div`也不同。在 CSS 中,元素通常有两种形式:替换的和非替换的。 30 | 31 | #### 替换元素 32 | 33 | **替换元素**是指那些内容会被其它东西所替换的元素,这些东西并不直接出现在文档内容里。HTML 中最为人所熟悉的例子大概就是`img`元素了,它会被存储在文档外部的一个图片文件所替代。事实上,`img`元素没有实在的内容,正如下面的简单示例中所展示的: 34 | 35 | 36 | 37 | 这个标记片段只包含元素名称和属性。 除非你把它指向外部内容(这里是由`src`属性指定的图片),这个元素不会显示任何内容。 如果把它指向有效的图片文件,则图片将被放置在文档中。反之,它将不显示任何内容,或者,浏览器将在这里放置一个“损坏图像”的占位符。 38 | 39 | 类似地,`input`元素也会被替换为单选按钮、复选框或文本输入框 —— 这取决与`input`元素的`type`属性。 40 | 41 | #### 非替换元素 42 | 43 | 大多数 HTML 元素是**非替换元素**。这意味着元素的内容会被用户代理(通常是浏览器)显示在一个由元素自己生成的“盒子”里。例如,`hi there`是一个非替换元素,文字“hi there”会由用户代理显示。对于段落、标题、表格单元格、列表以及 HTML 中的其他大部分元素都是如此。 44 | 45 | ### 元素显示角色 46 | 47 | 除了替换和非替换元素,CSS 还使用另外两种基本类型来区分元素:**块级(block-level)**和**行内级(inline-level)**。还有很多显示类型,但这两个是最基本的,也是绝大部分(如果不是全部)其他类型会涉及的类型。曾经花费时间在 HTML 标签和它们在web浏览器中显示上的开发者,对块级和行内类型不会陌生。元素在图1中展示。 48 | 49 | ![图1:HTML文档中的块级和行内元素](figure1.png) 50 | 51 | *图1:HTML文档中的块级和行内元素* 52 | 53 | #### 块级元素 54 | 55 | **块级元素**生成一个(默认情况下)元素框,填充其父元素的内容区域,并且在其两侧不能有其他元素。 换句话说,它在元素框之前和之后生成“断行”。 HTML 中最常见的块元素是`p`和`div`。 替换元素可以是块级元素,但通常不是。 56 | 57 | 列表项是一种特别的块级元素。 除了与其他块级元素一致的行为之外,它们还生成一个标记(通常是用于无序列表的项目符号和用于有序列表的数字)并“附加到”元素框。 除了这个标记,列表项与其他块级元素的行为完全相同。 58 | 59 | #### 行内元素 60 | 61 | **行内元素**在文本行内生成一个元素框,并且不会破坏该行的流。HTML 中最好的例子是`a`元素,其它还有`strong`和`em`。这些元素不会在自身之前或之后生成“断行”,所以它们可以出现在其它元素的内容之中,并且不会破坏其显示。 62 | 63 | 需要注意,虽然名称“块级”和“行内”与 HTML 中的块和行内元素有很多共同之处,但还有个重要区别:在 HTML 中,块级元素不能作为行内元素的后代;但在 CSS 中,对显示角色之间的嵌套没有限制。 64 | 65 | 要了解其工作原理,我们来考虑一个CSS属性`display`: 66 | 67 | | | DISPLAY | 68 | | ---- | ----- | 69 | |取值| [ `` ‖ `` ] | `` | `` | `` | `` | 70 | |定义|见下| 71 | |初始值|inline| 72 | |适用元素|所有元素| 73 | |计算值|按规范取值| 74 | |继承|否| 75 | |动画|否| 76 | 77 | **``** 78 | > block | inline | run-in 79 | 80 | **``** 81 | > flow | flow-root | table | flex | grid | ruby 82 | 83 | **``** 84 | > list-item && `? && [ flow | flow-root ]? 85 | 86 | **``** 87 | > table-row-group | table-header-group | table-footer-group | table-row | table-cell | table-column-group | table-column | table-caption | ruby-base | ruby-text | ruby-base-container | ruby-text-container 88 | 89 | **``** 90 | > contents | none 91 | 92 | **``** 93 | > inline-block | inline-list-item | inline-table | inline-flex | inline-grid 94 | 95 | 你可能已经注意到了这里有许多取值,只有其中三个是我提到过的:`block`、`inline`和`list-item`。这些取值的大部分会在本书其他部分介绍;例如`grid`和`inline-grid`涵盖在介绍栅格布局的独立的一章,跟表格相关的值都包含在介绍 CSS 表格布局的章节中。 96 | 97 | 现在我们把注意力放在`block`和`inline`上,看下面的代码: 98 | 99 | ~~~html 100 | 101 |

This is a paragraph with an inline element within > it.

102 | 103 | ~~~ 104 | 105 | 这里有两个块级元素(`body`和`p`)和一个行内元素(`em`)。根据 HTML 规范,`em`可以作为`p`的后代,但反过来则不行。通常HTML 的层级结构允许行内元素作为块级元素的后代,而不是相反。 106 | 107 | CSS则没有这样的限制,你可以保持现有的标签结构,然后修改这两个元素的显示角色: 108 | 109 | ~~~css 110 | p {display: inline;} 111 | em {display: block;} 112 | ~~~ 113 | 114 | 这使得元素在一个行内框里面生成了一个块级框,这在CSS中是完全合法的,不会破坏任何规范。但是,如果你想在 HTML 中使用相反的嵌套结构,那就有会问题了,像这样: 115 | 116 | ~~~html 117 |

This is a paragraph improperly enclosed by an inline element.

118 | ~~~ 119 | 120 | 不管你如何使用 CSS 来修改它们的显示角色,这在 HTML 中都是不合法的。 121 | 122 | 修改元素的显示角色在 HTML 文档中很有用,它对 XML 文档也至关重要。XML 文档一般没有默认的显示角色,而完全依赖文档开发者去定义它们。例如,如果你想要展示下面的 XML 片段: 123 | 124 | ~~~xml 125 | 126 | Cascading Style Sheets: The Definitive Guide 127 | Third Edition 128 | Eric A. Meyer 129 | O'Reilly and Associates 130 | November 2006 131 | 978-0-596-52733-4 132 | 133 | 134 | CSS Pocket Reference 135 | Third Edition 136 | Eric A. Meyer 137 | O'Reilly and Associates 138 | October 2007 139 | 978-0-596-51505-8 140 | 141 | ~~~ 142 | 143 | 因为`display`属性的默认值是`inline`,所以这块内容会默认被显示为行内文本,就像图 2 所示的那样。这样的排版不太有用。 144 | 145 | ![图2:一个XML文档的默认显示](figure2.png) 146 | 147 | *图2:一个XML文档的默认显示* 148 | 149 | 你可以用`display`来定义文档的基本板式: 150 | 151 | ~~~css 152 | book, maintitle, subtitle, author, isbn {display: block;} 153 | publisher, pubdate {display: inline;} 154 | ~~~ 155 | 156 | 这样把 7 种元素中的 5 个设置成块级元素,2 个设置成行内元素。块级元素会被像HTML中的`div`那样处理,两个行内元素会被类似`span`那样处理。 157 | 158 | 因为这种设置显示角色的基本能力,CSS 在各种场景下都非常有用。你可以从上面的规则开始,添加一些更具视觉效果的样式,然后得到像图 3 这样的显示效果。 159 | 160 | ![图3:添加了样式的XML文档](figure3.png) 161 | 162 | *图3:添加了样式的XML文档* 163 | 164 | 在详细学习如何编写 CSS 之前,我们先要看一下如何关联 CSS 和文档,毕竟,如果不把它们结合在一起,CSS 是无法对文档起作用的。我们从最熟悉的 HTML 设置开始。 165 | 166 | ## 结合CSS和HTML 167 | 168 | 我提到过 HTML 文档存在一个固有结构,这一点值得重复一下。实际上有个旧网页开发遗留的问题:我们太多人忘记了文档是应该有一个内在结构的,这与视觉上的结构是完全不同的。我们急于在 Web 上创建看起来最酷的网页,我们改造转换、修饰装点,全然忽视了页面应该包含具有一些结构意义的信息。 169 | 170 | 这种结构是 HTML 和 CSS 之间关系所固有的组成部分,没有它,关系就不会存在。为了更好地理解这种结构,我们把下面这个示例的HTML文档拆解来看: 171 | 172 | ~~~html 173 | 174 | 175 | Eric's World of Waffles 176 | 177 | 178 | 182 | 183 | 184 |

Waffles!

185 |

The most wonderful of all breakfast 186 | foods is the waffle—a ridged and cratered slab of home-cooked, 187 | fluffy goodness that makes every child's heart soar with joy. 188 | And they're so easy to make! Just a simple waffle-maker and some 189 | batter, and you're ready for a morning of aromatic ecstasy! 190 |

191 | 192 | 193 | ~~~ 194 | 195 | 代码的处理结果及应用的样式的如图 4 所示。 196 | 197 | ![图片4:一个简单文档](figure4.png) 198 | 199 | *图片4:一个简单文档* 200 | 201 | 现在我们来看文档关联CSS的几种方式。 202 | 203 | ### `link`标签 204 | 205 | 首先是`link`标签的使用: 206 | 207 | ~~~html 208 | 209 | ~~~ 210 | 211 | `link`标签是一个有些被忽视的标签,但它是在 HTML 规范中存在了许多年的合法标签,一直在等着被善加利用。它最初的目的是允许 HTML 开发者把包含链接标签的文档与其他文档关联起来。CSS使用`Link`标签把样式表链接到文档中,如图 5,一个名为`sheet1.css`的样式表被连接到文档。 212 | 213 | ![图片5:展示外部样式表如何被应用到文档](figure5.png) 214 | 215 | *图片5:展示外部样式表如何被应用到文档* 216 | 217 | 这些样式表不是 HTML 文档的一部分但仍被应用于文档中,它们被称为**外部样式表**,因为它们存在于 HTML 文档的外部(看图)。 218 | 219 | 链接必须放置在`head`元素内,外部样式才能成功加载,与`title`不同,它不能被放置在任何其它元素里。像图 5 所示的那样,web 浏览器会定位并加载样式表,然后把样式表中的任何样式都应用在 HTML 文档渲染中。图 5 中还展示了使用`@import`声明加载的外部样式`sheet2.css`。`@import`必须在包含它的样式表的开头[5](#f5),除此之外没有限制。 220 | 221 | 那么外部样式表是什么样的格式呢?和我们在前面章节中和在示例HTML文档中看到的那些样式一样,外部样式也是简单的规则列表,但是这些规则存储在自己的文件里面。要记住,HTML 和其它任何标记语言都不能放进样式表中——它只能包含样式规则。一个外部样式表的内容是这样的: 222 | 223 | ~~~csss 224 | h1 {color: red;} 225 | h2 {color: maroon; background: white;} 226 | h3 {color: white; background: black; font: medium Helvetica;} 227 | ~~~ 228 | 229 | 这就是它的全部内容——没有 HTML 标记或者注释,只有干净简单的样式声明。它们被存储在纯文本文件中,通常用`.css`作为后缀,例如`sheet1.css`。 230 | 231 | _**外部样式中不能包含任何文档标记,只能包含 CSS 规则和 CSS 注释,我们将在后面的章节解释它们。外部样式表中的标记可能会导致其中的全部或部分样式被忽略。**_ 232 | 233 | 文件扩展名不是必需的,但如果文件名不是以`.css`结尾,即使你在`link`元素中设置了正确的文件类型`text/css`,一些旧浏览器依然无法把文件识别为样式表。实际上,如果文件名不是以`.css`结尾,一些web服务器不会把文件当做`text/css`来处理,但通常这个问题可以通过修改服务器配置文件来解决。 234 | 235 | #### 属性 236 | 237 | 对于`link`标签的其它部分,属性和值都很直白。`rel`表示“关系”(relation),这里关系就是`stylesheet`(样式表)。`type`属性始终设置为`text/css`,这个值描述了被`link`标签加载的数据的类型。这样,web 浏览器就可以知道这个样式表是一个 CSS 样式表,这决定着浏览器如何处理它引入的数据。毕竟,将来可能会用到其它样式语言,所以声明你所使用的是哪种语言是有必要的。 238 | 239 | 接下来是`href`属性,这个属性的值是样式表的 URL。URL 可以是绝对或相对地址,这取决于你的需要。在示例中 URL 是相对的,显然它也可以是`http://meyerweb.com/sheet1.css.`这种形式。 240 | 241 | 最后是`media`属性,这个属性的值是一个或多个**媒体描述符**。媒体描述符是关于媒体类型和这些媒体的特性的规则,每个规则之间用逗号分隔。例如,你在屏幕和投影媒体上都可以使用一个这样的链接样式表: 242 | 243 | ~~~html 244 | 245 | ~~~ 246 | 247 | 媒体描述符可以设置得非常复杂,我们将会在本章中稍后的部分做详细解释,现在我们只使用基本的媒体类型。 248 | 249 | 注意,一个文档可以关联多个样式表。这时,只有那些包含`rel`属性值为`stylesheet` 250 | 的样式表会被用于文档的初始化显示。因此,如果你想分别链接两个名为`basic.css`和`splash.css`的样式表,看起来会像这样: 251 | 252 | ~~~html 253 | 254 | 255 | ~~~ 256 | 257 | 这种写法会使浏览器加载两个样式表,并合并每个样式表的规则,然后把它们全部应用于文档。例如 258 | 259 | ~~~html 260 | 261 | 262 |

This paragraph will be gray only if styles from the stylesheet 'basic.css' are applied.

263 |

This paragraph will be gray only if styles from the stylesheet 'splash.css' are applied.

264 | ~~~ 265 | 266 | 有一个可以但是并没有在示例代码中出现的属性`title`。这个属性并不常用,但它可能会在未来变得重要,如果使用不当会带来意想不到的效果。为什么呢?我们将在下一节中探讨。 267 | 268 | #### 备用样式表 269 | 270 | 可以定义**备用样式表**。它们是通过把`rel`属性的值设为`alternate stylesheet`来实现的,而且它们只有被用户选择的时候才会用于文档显示。 271 | 272 | 如果浏览器能够使用备用的样式表,它会用`link`元素的`title`属性值来生成一个可选择的样式列表。你可以像下面这样写: 273 | 274 | ~~~html 275 | 276 | 277 | 278 | ~~~ 279 | 280 | 然后用户就可以选择他们想用的样式,浏览器将会从第一个(这里被标记为“默认”(Default))切换到用户选择的任意一个。图6展示了这种选择机制的一个可能的(实际上是CSS再次兴起的早期所使用的)完成方式。 281 | 282 | ![图6:一个支持选择备用样式的浏览器](figure6.png) 283 | 284 | *图6:一个支持选择备用样式的浏览器* 285 | 286 | _**到2016年底,大部分基于Gecko引擎的浏览器已经支持了备用样式表,如Firefox和Opera。在Internet Explorer系列的浏览器中可以使用JavaScript实现支持,但是没有被浏览器原生支持。Webkit系列浏览器不支持选择备用样式表。(相比之下,图6所示的这么老旧的浏览器都提供了支持,真是令人惊讶。)**_ 287 | 288 | 通过给`title`属性赋相同的值,备用样式表可以分组组合。因此,你可以让用户在无论屏幕媒体还是打印媒体中都能选择不同的展示方式。例如: 289 | 290 | ~~~html 291 | 292 | 293 | 294 | 295 | ~~~ 296 | 297 | 如果用户在支持备用样式表选择机制的用户代理中选择了“Big Text”,那么`bigtext.css`将在屏幕媒体中为文档设置样式,而`print-bigtext.css`将会被用在打印媒体上。`sheet1.css`和`print-sheet1.css`不会被用在任何一个媒体中。 298 | 299 | 为什么会这样?因为一旦你为一个`rel`属性值为`styleshet`的`link`标签设置了`title`,你就指派了这个样式表为**优先样式表**。这表示它会比备用样式表优先被使用,会被用在文档第一次显示的时候。但是,当你选择了一个备用样式表的时候,优先样式表就**不会**再被使用了。 300 | 301 | 此外,如果你把多个样式表都指派为优先使用,那么除了一个之外所有其它的样式表都会被忽略。考虑下: 302 | 303 | ~~~html 304 | 305 | 306 | 307 | ~~~ 308 | 309 | 由于都被设置了`title`属性,三个`link`元素都被指定为优先样式表,但只有一个会被真正被作为优先样式表,而另外两个会完全被忽略。哪两个呢?没有办法确定。因为HTML并没有提供一种方式,来决定哪个样式应该被忽略,哪个样式应该被使用。 310 | 311 | 如果你根本不给样式表设置`title`,它将变成一个**持久的样式表**,并一直用在文档显示中。通常这正是开发者想要的。 312 | 313 | ### `style`元素 314 | 315 | 一种包含样式表的方法是使用`style`元素,它像这样显示在文档中: 316 | 317 | ~~~html 318 | 319 | ~~~ 320 | 321 | `style`需要设置`type`属性,与`link`标签一样,使用CSS文档的时候`type`值应该设置为`text/css`。 322 | 323 | 就像上面的示例所表示的,`style`元素总是以``作结束。`style`也可以指定一个`media`属性,它的作用与前面介绍的在链接样式表中的功能是一样的。 324 | 325 | 这种在`style`开始和结束标签之间的样式被称为**文档样式表**或者**内嵌样式表**(因为这种样式表是嵌入在文档里的)。内嵌样式表包含许多应用于文档的样式,也可以使用`@import`指令链接至多个外部样式。 326 | 327 | ### `@import`指令 328 | 329 | 现在我们开始讨论`style`标签内部。首先是与`link`非常类似的`@import`指令: 330 | 331 | ~~~css 332 | @import url(sheet2.css); 333 | ~~~ 334 | 335 | 像`link`一样,`@import`可以指示浏览器加载一个外部样式然后把它应用到 HTML 文档渲染中。它们之间主要的区别只是在于语法和命令的位置。正如我们看到的这样,`@import`是被包含在`style`中的。命令必须放在其他 CSS 规则之前,否则它不会生效。看这个例子: 336 | 337 | ~~~html 338 | 342 | ~~~ 343 | 344 | 与`link`相同的是,一个文档中可以有多个`@import`声明。但与`link`不同的是,`@import`指令中的每个样式表都会被加载和使用,`@import`不能设置备选样式表。因此,如果使用下面的代码: 345 | 346 | ~~~css 347 | @import url(sheet2.css); 348 | @import url(blueworld.css); 349 | @import url(zany.css); 350 | ~~~ 351 | 352 | 全部三个外部样式都会被加载,它们的样式规则也都会被用于文档显示中。 353 | 354 | 类似`link`,你可以在样式表的 URL 后添加媒体描述符,来限制样式表被用于一个或多个媒体: 355 | 356 | ~~~css 357 | @import url(sheet2.css) all; 358 | @import url(blueworld.css) screen; 359 | @import url(zany.css) projection, print; 360 | ~~~ 361 | 362 | 正如在`link`元素的章节中介绍的,媒体描述符可能会非常复杂,我们将在《第 20 章 媒体选择样式》中详细介绍。 363 | 364 | 如果你想要在一个外部样式表中使用另一个外部样式表,`@import`非常有用。因为外部样式表不能包含任何文档标记,`link`元素就无法使用,但`@import`却可以。所以,一个外部样式表可能是这样的: 365 | 366 | ~~~css 367 | @import url(http://example.org/library/layout.css); 368 | @import url(basic-text.css); 369 | @import url(printer.css) print; 370 | body {color: red;} 371 | h1 {color: blue;} 372 | ~~~ 373 | 374 | 这些不是真正使用的样式,但是你可以通过它们看到`@import`的用法。上例中同时使用了绝对和相对 URL,像`link`一样,两种都URL格式都可以使用。 375 | 376 | 还要注意,正如我们在示例文档中所做的,`@import`指令出现在样式表的开头。CSS 要求`@import`指令出现在样式表的其它规则之前。出现在其它规则(例如:`body {color: red;}`)之后的`@import`会被标准的用户代理所忽略。 377 | 378 | _**在Windows系统上的旧版的Internet Explorer浏览器中,即使`@import`指令放在其他规则之后,也不会被忽略。但其他浏览器会忽略位置不正确的`@import`指令,这很容易导致放置不正确的`@import`引起其他浏览器的显示错误。**_ 379 | 380 | ### HTTP链接 381 | 382 | 把 CSS 关联到文档还有一种非常晦涩的方式:你可以通过 HTTP 标头把它们链接在一起。 383 | 384 | 在 Apache 环境下,可以在`.htaccess`文件中添加CSS的文件引用来完成关联,例如: 385 | 386 | ~~~ 387 | Header add Link ";rel=stylesheet;type=text/css" 388 | ~~~ 389 | 390 | 支持该特性的浏览器会将引用的样式表与任何该`.htaccess`文件配置下的文档相关联,浏览器会把它当做一个链接样式表。另一个可能更有效的选择是,把相同的规则添加到服务器的`httpd.conf`文件中: 391 | 392 | ~~~xml 393 | 394 | Header add Link ";rel=stylesheet;type=text/css" 395 | 396 | ~~~ 397 | 398 | 对支持该特性的浏览器来说,这两种方式效果是一样的,唯一的区别是只是你在哪里声明链接而已。 399 | 400 | 你肯定注意到了前面所使用的“支持该特性的浏览器”。至2017年底,被广泛使用的浏览器中支持 HTTP 链接样式表的有 Firefox 系列和 Opera。这使得大部分情况下这项技术被限制在使用这些浏览器的开发环境中。在这些环境中,你可以在测试服务器上使用 HTTP 链接来标记测试环境网页,从而与发布的公共版网页区分开来。这项技术还是一种有趣的用来对 WebKit 和 Internet Explorer 系列浏览器隐藏样式的方法——假如你基于某些原因需要这么做的话。 401 | 402 | _**等价的技术存在于通用脚本语言中,如 PHP 和 IIS,这两种语言都允许开发者发出 HTTP 头。使用这些语言可以向服务器的文档中写入`link`元素。这种技术有浏览器的更好的支持:每个浏览器都支持`link`元素。**_ 403 | 404 | ### 行内样式 405 | 406 | 如果你只想简单地为一个单独元素设置一些样式,不需要使用内嵌或者外部样式表,使用 HTML 的`style`属性来设置**行内样式**即可: 407 | 408 | ~~~html 409 |

The most wonderful of all breakfast foods is the waffle—a ridged and cratered slab of home-cooked, fluffy goodness... 410 |

411 | ~~~ 412 | 413 | 除了位置在`body`之外的标签(`head`及`title`等),`style`属性可以设置在任何 HTML 标签上。 414 | 415 | `style`属性的语法很普通,跟`style`元素里面的规则声明很像,只不过花括号被换为双引号。`

`会把**当前段落**的文本设置为栗色,把背景设置为黄色,文档的其它部分不会受到这些样式声明的影响。 416 | 417 | 请注意,行内`style`属性只能放置样式规则声明块,而不是整个样式表。因此,`style`属性里既不能放置`@import`,也不能放进任何完整的样式规则,`style`属性的值只能被设置为样式规则花括号里面的那部分。 418 | 419 | `style`属性通常不建议使用,实际上它也不大可能出现在 HTML 之外的 XML 语言中。当把样式放置在`style`属性中时,许多 CSS 的主要优势——例如将整个文档或服务器的所有文档的样式集中组织的能力——便无法有效发挥了。从许多方面来说,使用行内样式并不比使用`font`标签好多少,尽管处理视觉效果的时候它确实(比`font`标签)更灵活。 420 | 421 | ## 样式表内容 422 | 423 | 那么,样式表的内容到底是什么样呢?像这样: 424 | 425 | ~~~css 426 | h1 {color: maroon;} 427 | body {background: yellow;} 428 | ~~~ 429 | 430 | 各种各样的嵌入样式表都是有这样的内容组成,无论内容长短,简单还是复杂。很少有文档的`style`元素不包含任何规则——尽管有的文档可能只包含一个简单的`@import`声明列表而没有像上面那样的真正的规则。 431 | 432 | 在开始本书的其它内容之前,我们首先需要确认样式表中能包含哪些东西,以及不能包含哪些东西。 433 | 434 | ### 标记 435 | 436 | **样式表中没有标记。**这似乎是显而易见的,但可能会让你惊讶的是,有一个 HTML 注释标记是例外,因为历史原因它允许存在于`style`元素中: 437 | 438 | ~~~html 439 | 443 | ~~~ 444 | 445 | 就这样。 446 | 447 | ### 规则结构 448 | 449 | 我们把结构分解,详细地说明规则的概念。 450 | 451 | 每条规则由两个基本部分构成:**选择器**和**声明块**。声明块由一个或多个**声明**组成,每个声明是一个**属性-值**对。每个样式表都是由一系列规则组成的。图 7展示了规则的组成部分: 452 | 453 | ![图7:规则的结构](figure7.png) 454 | 455 | *图7:规则的结构* 456 | 457 | 规则左侧的选择器,定义了文档中的哪些部分这条规则影响。图 7 中选择了`h1`元素,如果选择器是`p`,那所有的`p`(段落)元素将会被选择。 458 | 459 | 规则右侧是由一或多个声明组成的声明块。每个声明都由一个 CSS 属性和这个属性的取值组成。在图 7 中,声明块包含两个声明。第一个会使受影响的那部分文档的`color`属性值为`red`,第二个会使受影响的那部分文档的`background`属性值为`yellow`。因此,文档中所有的`h1`元素(由选择器决定)都会被设置为红色文字和黄色背景。 460 | 461 | #### 厂商前缀 462 | 463 | 有时你会看到CSS中存在像`-o-border-image`这样在前面带着短线和标签的声明。这被称作**厂商前缀(vendor prefixes)[6](#f10)**,浏览器厂商在提供试验性或专有(或两者)功能时,用它来标记属性、值或其他CSS内容。到 2016 年底已经有了很多厂商前缀,表 1 中列出了最常见的几种。 464 | 465 | *表1: 一些常见的厂商前缀* 466 | 467 | |前缀|厂商| 468 | |:----|:----- 469 | |-epub-|国际数字出版论坛 epub 格式 470 | |-moz-|基于 Mozilla 的浏览器(如:Firefox) 471 | |-ms-|Microsoft Internet Explorer 472 | |-o-|基于 Opera 的浏览器 473 | |-webkit-|基于 WebKit 的浏览器(如:Safari 和 Chrome) 474 | 475 | 如表 1 所示,厂商前缀的通常格式是短线-标签-短线,尽管有些(厂商的)前缀错误地省略了第一个短线。 476 | 477 | 厂商前缀的使用以及其后的滥用是一个漫长而又曲折的过程,讲述它超出了本书的范围。我们只需知道,它们一开始是作为厂商测试新功能的一种方式,从而有助于加速(不同浏览器之间)的互通性,而不至于被其它不能兼容的旧浏览器禁锢脚步。这避免了一系列问题,使得 CSS 幸免于在初期就被扼杀的厄运。然而不幸的是,随后前缀属性被 web 开发者无所顾忌地配置,最终导致了一系列新的问题。 478 | 479 | 到 2016 年底,厂商前缀正在逐步减少,旧的前缀属性和值正在从浏览器的实现中慢慢移除。也许你再也不需要写前缀 CSS 了,这是完全可能的,但你说不定从哪遭遇到它,或者从遗留代码里遇到它。 480 | 481 | ### 空格处理 482 | 483 | 虽然有些例外,但基本上 CSS 对规则间的空格不敏感,对规则内的空格则更加不敏感。 484 | 485 | 一般来说,CSS 处理空格的方式类似 HTML:任何空格字符的序列都被当做单个空格解析。因此,一个假想的`rainbow`规则可以格式化为下面的格式: 486 | 487 | ~~~css 488 | rainbow:infrared red orange yellow green blue indigo violet ultraviolet; 489 | rainbow: 490 | infrared red orange yellow green blue indigo violet ultraviolet; 491 | rainbow: 492 | infrared 493 | red 494 | orange 495 | yellow 496 | green 497 | blue 498 | indigo 499 | violet 500 | ultraviolet 501 | ; 502 | ~~~ 503 | 504 | 以及其他你能想到的分隔模式。唯一的限制是分割字符需要是空白:空格、tab 符、换行符,单个还是组合使用,随你喜欢。 505 | 506 | 类似地,你可以使用空白把一系列样式规则按照任何你偏好的风格格式化,这是无限多种可能中的五种格式: 507 | 508 | ~~~css 509 | html{color:black;} 510 | body {background: white;} 511 | p{ 512 | color: gray;} 513 | h2 { 514 | color : silver ; 515 | } 516 | ol 517 | { 518 | color 519 | : 520 | silver 521 | ; 522 | } 523 | ~~~ 524 | 525 | 在第一条规则中,空白被最大化地略去了。这种情况通常发生在 CSS “压缩”的时候,这时会把不影响语义的空格全部删除。前两条之后的规则逐渐加入更多空白,到最后一条规则,几乎每个可以被分隔的地方都被分开了。 526 | 527 | 以上的每种方式都是合法的,因此你应该选择一种最有意义的格式,即在你看来最易读的格式,然后坚持一贯地使用它。 528 | 529 | 有些地方是确切地需要空白的,最常见的例子是在属性值中分隔关键字列表,例如上面的假想 rainbow 例子中。这些地方必须用空白来分隔。 530 | 531 | ### CSS注释 532 | 533 | CSS是允许添加注释的。与 C/C++ 中用`/*`和`*/`包裹的注释类似: 534 | 535 | ~~~css 536 | /* This is a CSS1 comment */ 537 | ~~~ 538 | 539 | 象 C++ 中一样,注释可以连续多行: 540 | 541 | ~~~css 542 | /* This is a CSS1 comment, and 543 | it can be several lines long without 544 | any problem whatsoever. */ 545 | ~~~ 546 | 547 | 要记住,CSS注释不允许嵌套,像这样是不正确的: 548 | 549 | ~~~css 550 | /* This is a comment, in which we find 551 | another comment, which is WRONG 552 | /* Another comment */ 553 | and back to the first comment */ 554 | ~~~ 555 | 556 | _**一个可能会创建了“嵌套”注释的场景是,当想要把样式表中一大块包含了注释的代码临时注释掉时。因为 CSS 不允许嵌套注释,“外层”注释会在“内层”注释结束的时候就结束了。**_ 557 | 558 | 不妙的是,CSS中没有行注释符,如`//`和`#`(这个字符是 ID 选择器的保留字)。`/* */`是唯一的CSS注释方式。因此,如果你想要把注释放置在规则的同一行,就要小心放置的方式,例如,这是正确的方式: 559 | 560 | ~~~css 561 | h1 {color: gray;} /* This CSS comment is several lines */ 562 | h2 {color: silver;} /* long, but since it is alongside */ 563 | p {color: white;} /* actual styles, each line needs to */ 564 | pre {color: gray;} /* be wrapped in comment markers. */ 565 | ~~~ 566 | 567 | 这个例子里,如果单行注释没有关闭,会导致大部分样式表变成注释的一部分,也就不能生效了: 568 | 569 | ~~~css 570 | h1 {color: gray;} /* This CSS comment is several lines 571 | h2 {color: silver;} long, but since it is not wrapped 572 | p {color: white;} in comment markers, the last three 573 | pre {color: gray;} styles are part of the comment. */ 574 | ~~~ 575 | 576 | 在这个例子中,只有第一行规则(`h1 {color: gray;}`)会被应用于文档。其它的则被浏览器的渲染引擎当做注释的一部分而忽略掉了。 577 | 578 | _**CSS注释会被CSS解析器当做不存在一样,也不会当做空白处理,这意味着你可以把注释放进规则中间,甚至放在声明里![7](#f11)**_ 579 | 580 | ## 媒体查询 581 | 582 | 通过媒体查询,开发者可以定义不同媒体环境中浏览器可以使用的样式表。过去,这是通过使用`media`属性来为`link`元素或`style`元素设置媒体类型,以及通过`@import`或`@media`声明的媒体描述符来处理的。现在媒体查询使这个概念更进一步,允许开发者通过使用所谓的媒体描述符,基于给定媒体类型的特性来选择样式表。 583 | 584 | ### 使用 585 | 586 | 媒体查询可以使用在以下位置: 587 | 588 | - `link`元素的`media`属性。 589 | - `style`元素的`media`属性。 590 | - `@import`声明的媒体描述符部分。 591 | - `media`声明的媒体描述符部分。 592 | 593 | 媒体查询可以是简单的媒体类型,也可以是媒体类型和特性的复杂组合。 594 | 595 | ### 简单媒体查询 596 | 597 | 在了解媒体查询的全部可能性之前,我们先看一些简单的媒体块的例子。假如当样式在投影设备例如幻灯片中时,我们想要一些不同的样式。这里有两行简单的 CSS: 598 | 599 | ~~~css 600 | h1 {color: maroon;} 601 | @media projection { body {background: yellow;} 602 | } 603 | ~~~ 604 | 605 | 在这个例子中,`h1`元素会在所有媒中都显示为栗色,但`body`元素仅会在投影媒体上被设置为黄色背景。 606 | 607 | 可以在一个样式表中加入许多`@media`块,每个拥有自己的媒体描述符(在后面的章节中详细介绍)。如果你愿意,甚至可以把所有规则封装进一个`@media`模块: 608 | 609 | ~~~css 610 | @media all { 611 | h1 {color: maroon;} 612 | body {background: yellow;} 613 | } 614 | ~~~ 615 | 616 | 但是由于这种写法与去掉第一行和最后一行之后的写法没有什么区别,因此这么做没有什么意义。 617 | 618 | 例子中的`projection`和`all`就是设置媒体查询的地方。查询依赖于一系列描述媒体类型和媒体参数(例如分辨率或者显示高度)的集合,以此决定何时应用 CSS 块。 619 | 620 | ### 媒体类型 621 | 622 | 媒体类型最基础的形式是**媒体类型**,它们首次出现于 CSS2。它们是表示不同类型媒体的简单标签。它们是: 623 | 624 | - `all` 625 | > 用于所有演示媒体。 626 | 627 | - `print` 628 | > 用于可视用户打印文档以及显示文档的打印预览。 629 | 630 | - `screen` 631 | > 用于在桌面电脑显示器等屏幕媒体中显示文档。在此类系统上运行的所有 Web 浏览器都是屏幕媒体用户代理。 632 | 633 | _**在撰写本文时[8](#f6),一些浏览器还支持`projection`类型,允许把文档显示成幻灯片;一些移动设备浏览器支持`handheld`类型,但并不十分可靠。**_ 634 | 635 | 可使用逗号分隔的列表指定多个媒体样式。下面的四个例子使用了相同的方式,把样式表(或样式规则代码块)应用于屏幕和投影媒体。 636 | 637 | ~~~html 638 | 639 | 640 | ~~~ 641 | 642 | ~~~css 643 | @import url(frobozz.css) screen, print; 644 | @media screen, print {...} 645 | ~~~ 646 | 647 | 当向这些媒体类型添加特性描述符(例如描述媒体分辨率和色深的值)时,事情将变得更加有趣。 648 | 649 | ### 媒体描述符 650 | 651 | 为`link`元素或者`@import`声明设置过媒体类型的开发者,将会对媒体查询(描述符)的位置非常熟悉。下面是在彩色打印机上渲染文档时应用外部样式表的两种基本等效的方法: 652 | 653 | ~~~html 654 | 655 | ~~~ 656 | 657 | ~~~css 658 | @import url(print-color.css) print and (color); 659 | ~~~ 660 | 661 | 任何使用媒体类型的地方,都可以使用媒体查询(描述符)。这意味着对上面的例子,可以使用逗号分隔可以列出多个查询: 662 | 663 | ~~~html 664 | 665 | ~~~ 666 | 667 | ~~~css 668 | @import url(print-color.css) print and (color), screen and (color-depth: 8); 669 | ~~~ 670 | 671 | 任何情况下,只要任何一个(逗号分隔的)媒体查询的判断结果为“真”,就会使用关联的样式表。因此,在前面的`@import`中,`print-color.css`将会被应用于彩色打印机或彩色投影环境的渲染。如果在黑白打印机上打印,两个查询的结果都是“假”,则`print-color.css`不会被应用于文档,对于任何屏幕媒体都是如此。 672 | 673 | 每个媒体描述符由一个媒体类型和一或多个媒体特性组成,每个媒体特性描述符都被包括在括号中。如果没有指定媒体类型,它将被默认设置为`all`,因此下面两个示例是完全等价的: 674 | 675 | ~~~css 676 | @media all and (min-resolution: 96dpi) {...} 677 | 678 | @media (min-resolution: 960dpi) {...} 679 | ~~~ 680 | 681 | 一般来说,媒体特性描述符的格式类似于CSS中的属性-值对,但有一些区别。最明显的区别是可以指定一些没有值的特性,例如,使用`(color)`来匹配任何基于颜色的媒体,而使用`(color: 16)`来匹配16位色深的颜色媒体。实际上,不含值的描述符是一个对特性是否存在的一个真/假值判断:`(color)`表示判断“是否是颜色媒体?”。 682 | 683 | 多个特性描述符可以使用逻辑关键字`and`链接,媒体查询里面有两个逻辑关键字: 684 | 685 | - **`and`** 686 | 使用这种方式链接两个或多个媒体特性时,只有当每个媒体特性都为真,总的查询结果才为真。例如,`(color) and (orientation: landscape) and (min-device-width: 800px)`表示三个条件必须都被满足:当媒体环境具有颜色、横向显示,而且设备的显示宽度至少为800像素时,样式表才会被使用。 687 | 688 | - **`not`** 689 | 对整个查询求反,如果所有的条件都为真,样式表则不会被使用。例如,`not (color) and (orientation: landscape) and (min- device-width: 800px)`表示如果三个条件被满足,则表达式会被否定。因此,当媒体环境具有颜色、横向显示,并且设备显示宽度至少为800像素时,样式表不会被使用;反之在其它任何情况下,样式表都会被使用。 690 | 691 | 请注意,`not`关键字只能用在媒体查询的开头。`(color) and not (min-device-width: 800px)`这样的用法是不合法的,在这种情况下,查询会被忽略。同样需要注意的是,太旧的浏览器会因为无法理解媒体查询而总是跳过媒体描述符以`not`开头的样式表。 692 | 693 | 媒体查询中没有`or`关键字,但分隔查询列表的逗号可以起到“或”的作用——`screen, print`表示“如果媒体是屏幕或打印机,则应用样式”。设置`screen and (max-color: 2) or (monochrome)`将会被忽略,应该写成`screen and (max-color: 2), screen and (monochrome)`来代替。 694 | 695 | 另外还有一个关键字`only`,专门用于向后兼容。是的,你没看错。 696 | 697 | - **`only`** 698 | 用于对无法理解媒体查询的旧浏览器隐藏样式表。例如,为了在所有媒体但仅在能够理解媒体查询的浏览器上应用样式表,写做`@import url(new.css) only all`。对于能够理解媒体查询的浏览器,`only`关键字会被忽略,样式表会被使用;对不能理解媒体查询的浏览器,`only`关键字会创建一个显式的媒体类型`only all`,而这是非法的,因此样式表不会应用于这样的浏览器中。要注意,`only`关键字只能用在媒体查询的开头。 699 | 700 | ### 媒体特性描述符和值类型 701 | 702 | 我们已经在示例中见过了一些媒体特性描述符,但还不完整,下面是所有可用描述符的列表(至 2017 年底): 703 | 704 | - `width` 705 | - `min-width` 706 | - `max-width` 707 | - `device-width` 708 | - `min-device-width` 709 | - `max-device-width` 710 | - `height` 711 | - `min-height` 712 | - `max-height` 713 | - `device-height` 714 | - `min-device-height` 715 | - `max-device-height` 716 | - `aspect-ratio` 717 | - `min-aspect-ratio` 718 | - `max-aspect-ratio` 719 | - `device-aspect-ratio` 720 | - `min-device-aspect-ratio` 721 | - `max-device-aspect-ratio` 722 | - `color` 723 | - `min-color` 724 | - `max-color` 725 | - `color-index` 726 | - `min-color-index` 727 | - `max-color-index` 728 | - `monochrome` 729 | - `min-monochrome` 730 | - `max-monochrome` 731 | - `resolution` 732 | - `min-resolution` 733 | - `max-resolution` 734 | - `orientation` 735 | - `scan` 736 | - `grid` 737 | 738 | 另外还加入了两个新的值类型 739 | 740 | - `` 741 | - `` 742 | 743 | 我们将在第 20 章对描述符和值进行完整的结束,以及介绍如何使用它们。 744 | 745 | ## 特性查询 746 | 747 | 2015 到 2016 年间,CSS 获得了一种能力,通过判断用户代理是否支持特定的属性-值组合来应用样式块,被称作**特性查询**。 748 | 749 | 结构上它们与媒体查询很相似。比如你只想为支持`color`属性的元素添加颜色(当然是支持的),可以这样: 750 | 751 | ~~~css 752 | @supports (color: black) { 753 | body {color: black;} 754 | h1 {color: purple;} 755 | h2 {color: navy;} 756 | } 757 | ~~~ 758 | 759 | 效果是这样的:“如果你能识别属性-值组合`color: black`并能用它做点什么,就使用这些样式,否则忽略这些样式。”对于不能理解`@supports`的用户代理,整个代码块都会被跳过。 760 | 761 | 特性查询是实现渐进增强(progressive enhance)的完美方式。例如,为现有的浮动行内块(float-and-inline-block)布局添加一些栅格布局,你可以保留旧的布局方案然后在样式表里添加这样的块: 762 | 763 | ~~~css 764 | @supports (display: grid ) { 765 | section#main {display: grid;} 766 | /* styles to switch off old layout positioning */ 767 | /* grid layout styles */ 768 | } 769 | ~~~ 770 | 771 | 理解栅格布局的浏览器会识别这个代码块,覆盖旧的页面布局样式,并使用未来那些基于栅格的样式。太旧的不能理解栅格布局的浏览器很可能也无法理解`@supports`,所以它们会跳过整个块,就像它没有出现过一样。 772 | 773 | 特性查询可以相互嵌套,也当然可以嵌套在媒体查询中,反过来也可以。你可以基于 flex 盒布局写屏幕和打印样式,把媒体快包在`@supports (display: flex)`块中: 774 | 775 | ~~~css 776 | @supports (display: flex) { 777 | @media screen { 778 | /* screen flexbox styles go here */ 779 | } 780 | @media print { 781 | /* print flexbox styles go here */ 782 | } 783 | } 784 | ~~~ 785 | 786 | 反过来,你也可以在多个响应式媒体查询块中添加`@supports()`块: 787 | 788 | ~~~css 789 | @media screen and (max-width: 30em){ 790 | @supports (display: flex) { 791 | /* small-screen flexbox styles go here */ 792 | } 793 | } 794 | @media screen and (min-width: 30em) { 795 | @supports (display: flex) { 796 | /* large-screen flexbox styles go here */ 797 | } 798 | } 799 | ~~~ 800 | 801 | 如何组织代码块完全取决于你自己。 802 | 803 | 和媒体查询一样,特性查询也允许使用逻辑操作符。例如当用户代理同事支持栅格布局和 CSS 形状的时候才应用样式: 804 | 805 | ~~~css 806 | @supports (display: grid) and (shape-outside: circle()) { 807 | /* grid-and-shape styles go here */ 808 | } 809 | ~~~ 810 | 811 | 等同于下面的写法: 812 | 813 | ~~~css 814 | @supports (display: grid) { 815 | @supports (shape-outside: circle()) { 816 | /* grid-and-shape styles go here */ 817 | } 818 | } 819 | ~~~ 820 | 821 | 然而,可用的操作符并不仅有`and`。CSS Shapes (在第 10 章详细介绍)是说明`or`用处的好例子,因为很长一段时间内 WebKit 只能通过厂商前缀属性支持 CSS 形状。所以当想要使用形状的时候,可以这样使用特性查询: 822 | 823 | ~~~css 824 | @supports (shape-outside: circle()) or (-webkit-shape-outside: circle()) { 825 | /* shape styles go here */ 826 | } 827 | ~~~ 828 | 829 | 尽管你还是必须使用形状属性的前缀和非前缀两个版本,但这样可以让你向后兼容的 WebKit 的发行版本,同时支持那些支持形状但不需要前缀属性的浏览器。 830 | 831 | 某些情况下,你想使用与正在(特性查询中)测试的属性不同的属性,会非常方便。回到栅格布局的例子,如果你要在使用栅格布局的时候修改元素的外边距,这是简单的实现版本: 832 | 833 | ~~~css 834 | div#main {overflow: hidden;} 835 | div.column {float: left; margin-right: 1em;} 836 | div.column:last-child {margin-right: 0;} 837 | 838 | @supports (display: grid) { 839 | div#main {display: grid; grid-gap: 1em 0; overflow: visible;} 840 | div#main div.column {margin: 0;} 841 | } 842 | ~~~ 843 | 844 | 反过来也可以,当不支持栅格布局时添加样式: 845 | 846 | ~~~css 847 | @supports not (display: grid) { 848 | /* grid-not-supported styles go here */ 849 | } 850 | ~~~ 851 | 852 | 在单个查询中可以联合使用逻辑操作符,但应该用圆括号保持逻辑清晰。例如在这种情况下使用样式:支持颜色,同时支持栅格和 flex 布局中的一个: 853 | 854 | ~~~css 855 | @supports (color: black) and ((display: flex) or (display: grid)) { 856 | /* styles go here */ 857 | } 858 | ~~~ 859 | 860 | 注意`or`操作符有一组额外的圆括号,把栅格和 flex 布局包起来,这组圆括号是必需的。如果没有这组括号的话,整个表达式可能匹配失败,导致整个样式被跳过。换句话说,不要这样写: 861 | 862 | ~~~css 863 | @supports (color: black) and (display: flex) or (display: grid) { 864 | ~~~ 865 | 866 | 最后,你可能想知道为什么在特性查询中需要同时传入属性和值,毕竟当使用形状的时候只需要测试`shape-outside`就行了,不是吗?这是因为:浏览器可以轻易支持一个属性但不并支持这个属性的任何一个值。栅格布局是一个好例子,假如你可以这样测试对栅格的支持: 867 | 868 | ~~~css 869 | @supports (display) { 870 | /* grid styles go here */ 871 | } 872 | ~~~ 873 | 874 | 额,就算是 IE4 都支持 `display` 属性。所有理解`@supports`的浏览器肯定也理解`display`属性和它的很多值——但未必支持`grid`。这就是特性查询总是同时测试属性和值的原因。 875 | 876 | _**请记住这是*特性*查询,不是正确性查询。某个浏览器能够理解你测试的属性,但对这个属性的实现可能有 bug。所以特性查询并不能给你一个浏览器*正确地*支持某些东西的精确保障。查询结果匹配只是表示浏览器理解你告诉它的东西,并试图去支持它。**_ 877 | 878 | ## 总结 879 | 880 | CSS 可以完全改变用户代理显示元素的方式。这种改变可以使用`display`属性在基本的显示级别上执行,并且通过把样式表关联到文档的不同方式来执行,用户不会知道这是通过外部还是内嵌样式表,甚至行内样式表完成的。外部样式表的重要性在于允许开发者把一个站点的所有展示信息放在一个地方,然后把所有文档指向这个地方。这不仅使站点更新和维护变得容易,还因为在文档中移除了所有展示信息而节省了带宽。使用`@supports()`,可以仅使用原生 CSS 实现一些基本的渐进增强策略。 881 | 882 | 为了充分利用CSS的能力,开发者需要弄清楚如何将一组样式与文档中的元素相关联。为了完全理解CSS是如何做到这一点的,开发者需要透彻地领会 CSS 选择文档片段的方式,这就是下一章的主题。 883 | 884 | * * * 885 | 886 | 1. 译注:Firefox等浏览器所使用的引擎。[↩](#a1) 887 | 888 | 1.1 译注:浏览器 viewport 之外的部分,如:地址栏、书签栏、标签栏等。Definition: Chrome is the visual design elements that give users information about or commands to operate on the screen's content (as opposed to being part of that content). These design elements are provided by the underlying system — whether it be an operating system, a website, or an application — and surround the user's data. 参见 Issue: [#3](https://github.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/issues/3) [↩](#a1_1) 889 | 890 | 2. 译注:Web发展早期第一个普及的浏览器。[↩](#a2) 891 | 892 | 3. 译注:Recommendation 是W3C的推荐标准,标准已经历了理论上和实际上的评审和测试,由W3C作签署,可以广泛应用。这是W3C提案的最终成熟的阶段。)[↩](#a3) 893 | 894 | 4. 译注:Candidate Recommendation是W3C的候选推荐标准,候选推荐标准与工作草案相比更加稳定,提案的重大的特性大部分已经锁定。[↩](#a4) 895 | 896 | 5. 译注:`@import`规则必须放在其他除了@charset规则以外的CSS规则的前面[↩](#a5) 897 | 898 | 6. 译注:本章最初写于2012年,与全书一起出版于2017年[↩](#a6) 899 | 900 | 7. 译注:vendor prefixes有时被翻译为“浏览器引擎前缀”或“第三方前缀”,译法未见统一,这里采用直译“厂商前缀”,以突出“vendor”的“厂商”之意。[↩](#a10) 901 | 902 | 8. 译注:例如`h1 { co/* comments */lor: red; }`。[↩](#a11) 903 | -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/figure1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/1_CSS_and_Documents/figure1.png -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/figure2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/1_CSS_and_Documents/figure2.png -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/figure3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/1_CSS_and_Documents/figure3.png -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/figure4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/1_CSS_and_Documents/figure4.png -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/figure5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/1_CSS_and_Documents/figure5.png -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/figure6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/1_CSS_and_Documents/figure6.png -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/figure7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/1_CSS_and_Documents/figure7.png -------------------------------------------------------------------------------- /docs/1_CSS_and_Documents/web-yang-shi-li-shi-jian-jie.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/1_CSS_and_Documents/web-yang-shi-li-shi-jian-jie.md -------------------------------------------------------------------------------- /docs/2_Selectors/README.md: -------------------------------------------------------------------------------- 1 | # 选择器 2 | 3 | CSS 的一个主要优势——尤其对设计者而言——是它能够轻松地把一组样式应用到同一类型的所有元素。印象不够深刻?想象这样的场景:通过编辑单行 CSS,你可以修改所有标题的颜色。不喜欢正在使用的蓝色?修改一行代码,把它们都变成紫色、黄色、栗色等等任何想要的颜色。这可以让你,设计师,专注于设计而不是繁琐的工作。下次会议中,有人想看绿色标题,你只需要编辑样式然而点击重新加载。瞧!几秒钟就完成了,每个人都可以看到。 4 | 5 | 当然,CSS 不能解决所有问题——比如,它不能用来改变 PNG 图片的颜色空间,至少现在还不能——但它确实让全局修改变得容易多了。我们先从选择器和结构开始。 6 | 7 | ## 基本样式规则 8 | 9 | 如上所述,CSS 的核心特性是将某些样式应用于文档中的整个元素类型的能力。例如,如果你想把所有`h2`元素的文本显示为灰色,使用老套的 HTML,你必须在所有的`h2`元素中插入`...`标签;使用`style`属性也不好,这需要你在所有的`h2`元素上添加`style="color: gray;"`: 10 | 11 | ~~~html 12 |

This is h2 text

13 |

This is h2 text

14 | ~~~ 15 | 16 | 显然,如果你的文档里面有许多`h2`元素,修改过程将是乏味的。更糟糕的是,如果你之后又想把所有的`h2`从灰色变成绿色,你又得重新开始手动设置一遍便签。(没错,以前就是这么干的!) 17 | 18 | CSS 让你可以创建易于编辑的规则,并把它们应用于所有你定义的文本元素(下一部分将解释规则如何生效)。例如,简单地写一次下面的规则,把所有的`h2`元素都变成灰色: 19 | 20 | ~~~css 21 | h2 {color: gray;} 22 | ~~~ 23 | 24 | 如果你想把所有`h2`的文本变成另一种颜色——比如银色——只要简单地选择(属性)值: 25 | 26 | ~~~css 27 | h2 {color: silver;} 28 | ~~~ 29 | 30 | ### 元素选择器 31 | 32 | 元素选择器通常都是 HTML 元素,但也有例外。例如,如果 CSS 文件的样式是用于 XML 文档的,元素选择器可能会是这样: 33 | 34 | ~~~css 35 | quote {color: gray;} 36 | bib {color: red;} 37 | booktitle {color: purple;} 38 | myElement {color: red;} 39 | ~~~ 40 | 41 | 换句话说,文档的元素被用作最基本的选择器。在 XML 中,选择器可以是任何东西,因为 XML 允许创建新的标记语言,任何东西都可以作为元素名称。另一方面,如果为 HTML 文档添加样式,选择器一般是许多 HTML 元素之一,如`p`,`h3`,`em`,`a`,甚至`html`元素本身。例如: 42 | 43 | ~~~css 44 | html {color: black;} 45 | h1 {color: gray;} 46 | h2 {color: silver;} 47 | ~~~ 48 | 49 | 样式表的结果在图1-1中展示: 50 | 51 | ![图1-1:简单文档的简单样式](figure1-1.png) 52 | 53 | *图1-1:简单文档的简单样式* 54 | 55 | 当你直接全局地给元素设置了样式,你可以把样式从一个样式移到另一个样式上。如果你想要图 1-1 中的段落文本而不是`h1`元素是灰色,没问题,只要把`h1`选择器换成`p`就行了; 56 | 57 | ~~~css 58 | html {color: black;} 59 | p {color: gray;} 60 | h2 {color: silver;} 61 | ~~~ 62 | 63 | 结果在图1-2中展示: 64 | 65 | ![图1-2:把样式从一个元素移到另一个上](figure1-2.png) 66 | 67 | *图1-2:把样式从一个元素移到另一个上* 68 | 69 | ### 声明和关键字 70 | 71 | 声明块包含一或多条声明。一条声明的格式总是一个**属性**后面跟着一个冒号,然后一个**值**后面跟着一个分号。冒号和分号后面可以有零或多个空白。几乎所有的值都是单个关键字或者空白分隔的当前属性允许的多个关键字列表。如果在一条声明中使用了错误的属性或值,整条规则都会被忽略。因此,下面这两条声明是无效的: 72 | 73 | ~~~css 74 | brain-size: 2cm; /* unknown property 'brain-size' */ 75 | color: ultraviolet; /* unknown value 'ultraviolet' */ 76 | ~~~ 77 | 78 | 属性值可以使用多个关键字的时候,关键字通常用空白分隔,有些情况下需要斜线(`/`)。很多属性可以接收多个关键字(如`font`属性),但不是全部属性都可以。如果想为段落字体设置中等大小的 Helvetica 字体,就像在图 1-3 中显示的: 79 | 80 | ![图1-3:属性值包含多个关键字的结果](figure1-3.png) 81 | 82 | *图1-3:属性值包含多个关键字的结果* 83 | 84 | 规则将是这样: 85 | 86 | ~~~css 87 | p {font: medium Helvetica;} 88 | ~~~ 89 | 90 | 注意两个关键字`medium`和`Helvetica`之间的空白(第一个是字体大小,第二个是字体名称)。空白使用户代理可以分辨出两个关键字并正确地使用它们。分号指明当前声明已经结束。 91 | 92 | 这些空白分隔的词被称为**关键字**,因为它们在一起组成了属性的值。例如下面这个虚拟的规则: 93 | 94 | ~~~css 95 | rainbow: red orange yellow green blue indigo violet; 96 | ~~~ 97 | 98 | 当然不存在`rainbow`这个属性,它只是被当做例子来进行说明。`rainbow`的值是`red orange yellow green blue indigo violet`,这 7 个关键字放在一起组成了一个唯一的值。我们可以像下面这样重新定义`rainbow`的值: 99 | 100 | ~~~css 101 | rainbow: infrared red orange yellow green blue indigo violet ultraviolet; 102 | ~~~ 103 | 104 | 现在我们有了一个由 9 个而不是 7 个关键字组成的新值。虽然这两个值看起来很像,但他们就像 0 和 1 一样是不同而且唯一的。这里好像有点抽象,但它对理解一些特性和层叠(在本书后面部分讨论)的微妙影响是至关重要的。 105 | 106 | 如我们所见。CSS 关键字通常使用空白分隔。在 CSS2.1 中有个例外:`font`属性值可以使用正斜杠(`/`)分隔两个特殊的关键字,例如: 107 | 108 | ~~~css 109 | h2 {font: large/150% sans-serif;} 110 | ~~~ 111 | 112 | 斜线分隔的关键字设置元素的字体大小和行高,这是`font`声明中唯一允许使用斜线的地方,`font`的所有其他关键字都使用空白分隔。 113 | 114 | 斜线已经可以使用在其他一些属性值中,包括可能不限于下面的属性: 115 | 116 | - `background` 117 | - `border-image` 118 | - `border-radius` 119 | - `grid` 120 | - `grid-area` 121 | - `grid-column` 122 | - `grid-row` 123 | - `grid-template` 124 | - `mask-border` 125 | 126 | 还有些关键字使用逗号分隔。声明多个值时,例如多背景图片、变换属性和阴影,声明使用逗号分隔。另外函数参数,如`linear gradiennts`和`transform`等,也使用逗号分隔,示例: 127 | 128 | ~~~css 129 | .box {box-shadow: inset -1px -1px white, 130 | 3px 3px 3px rgba(0,0,0,0.2); 131 | background-image: url(myimage.png), 132 | linear-gradient(180deg, #FFF 0%, #000 100%); 133 | transform: translate(100px, 200px); 134 | } 135 | a:hover {transition: color, background-color 200ms ease-in 50ms;} 136 | ~~~ 137 | 138 | 这些是基础的简单声明,但它们也可以变得非常复杂。下一部分我们将要展示CSS有多么强大。 139 | 140 | ## 分组 141 | 142 | 如我们所见,把一个简单样式应用在一个简单选择器上是非常简单的,但是如果你想把相同的样式引用在多个元素上应该怎么做呢?这种场景下,你会想要把多个选择器或多个样式应用在一个或一组元素上。 143 | 144 | ### 分组选择器 145 | 146 | 如果你想让`h2`元素和段落都显示灰色文本,最简单的方式是使用下面的声明: 147 | 148 | ~~~css 149 | h2, p {color: gray;} 150 | ~~~ 151 | 152 | 把`h2`和`p`选择器放置在规则左边并用逗号分隔,这种方式定义了一条把右边样式(`color: gray;`)应用于两个选择器的规则。逗号告诉浏览器规则里面是两个不同的选择器,如果去掉逗号,会使语句变成另外一条含义完全不同的规则。(参见后面的章节“后代选择器”。) 153 | 154 | 分组的选择器数目没有限制,例如,如果你想把一大堆元素都设置成灰色,你可以用这样的规则: 155 | 156 | ~~~css 157 | body, table, th, td, h1, h2, h3, h4, p, pre, strong, em, b, i {color: gray;} 158 | ~~~ 159 | 160 | 分组允许开发者可以大幅压缩样式分配,从而使样式表更精简。下面两种写法的结果是一样的,哪一种更容易输入是很明显的: 161 | 162 | ~~~css 163 | h1 {color: purple;} 164 | h2 {color: purple;} 165 | h3 {color: purple;} 166 | h4 {color: purple;} 167 | h5 {color: purple;} 168 | h6 {color: purple;} 169 | 170 | h1, h2, h3, h4, h5, h6 {color: purple;} 171 | ~~~ 172 | 173 | 分组允许做出一些有趣的选择,例如下面例子中的写法都是等效的,每个例子展示了一种分组选择器和声明的不同方式: 174 | 175 | ~~~css 176 | /* group 1 */ 177 | h1 {color: silver; background: white;} 178 | h2 {color: silver; background: gray;} 179 | h3 {color: white; background: gray;} 180 | h4 {color: silver; background: white;} 181 | b {color: gray; background: white;} 182 | 183 | /* group 2 */ 184 | h1, h2, h4 {color: silver;} 185 | h2, h3 {background: gray;} 186 | h1, h4, b {background: white;} 187 | h3 {color: white;} 188 | b {color: gray;} 189 | 190 | /* group 3 */ 191 | h1, h4 {color: silver; background: white;} 192 | h2 {color: silver;} 193 | h3 {color: white;} 194 | h2, h3 {background: gray;} 195 | b {color: gray; background: white;} 196 | ~~~ 197 | 198 | 每个例子都会生成图 1-4 显示的结果。(这些样式使用的分组声明,将在接下来的“分组声明”中探讨。) 199 | 200 | ![图4:等效样式表的结果](figure1-4.png) 201 | 202 | *图4:等效样式表的结果* 203 | 204 | #### 通配选择器 205 | 206 | CSS2 引入了一个新的简单选择器叫做**通配选择器**,使用星号(`*`)标注。这个选择器就像一张百搭牌,可以匹配所有元素。例如,要把文档中的每个元素(文本)都设置成红色,可以这样写: 207 | 208 | ~~~css 209 | * {color: red;} 210 | ~~~ 211 | 212 | 此声明等效于一个列出文档中所有元素的分组选择器。通配选择器允许你以一种有效的方式为文档中每个元素的`color`属性设置一个值`red`。但是,要注意,虽然通配选择器很方便,它的特度是 0-0-0,但因为会匹配所有元素,它可能带来意外的后果,我们将在本书后面的部分讨论。 213 | 214 | ### 分组声明 215 | 216 | 规则中分组选择器,也可以分组声明。假如你想把所有的`h1`元素设置为紫色、18 像素高的 Helvetica 字体显示在水色背景上(你不介意闪瞎用户),你可以把样式写成这样: 217 | 218 | ~~~css 219 | h1 {font: 18px Helvetica;} 220 | h1 {color: purple;} 221 | h1 {background: aqua;} 222 | ~~~ 223 | 224 | 但这种方式是低效的——想象一下为每个元素创建一个10或15个样式的列表!你可以把声明组合在一起来替代前面的写法: 225 | 226 | ~~~css 227 | h1 {font: 18px Helvetica; color: purple; background: aqua;} 228 | ~~~ 229 | 230 | 这种写法和上面的三行样式表是一样的结果。 231 | 232 | 要注意分组来写的时候每条声明后面的分号至关重要。浏览器会忽略样式表中的空白,因此用户代理要依赖正确的语法来解析样式表。你可以这样格式化样式表: 233 | 234 | ~~~css 235 | h1 { 236 | font: 18px Helvetica; 237 | color: purple; 238 | background: aqua; 239 | } 240 | ~~~ 241 | 242 | 也可以通过移除不必要的空白压缩 CSS: 243 | 244 | ~~~css 245 | h1{font:18px Helvetica;color:purple;background:aqua;} 246 | ~~~ 247 | 248 | 上例的后三种写法对服务器来说是等效的,但第二种更易于人类阅读,也是 CSS 开发环境中的推荐写法。(也许压缩 CSS 是出于提高网络性能的原因,但通常这应该由服务器端脚本、网络缓存以及其他服务等来完成。) 249 | 250 | 如果第二个例子中漏掉了第二个分号,用户代理会把样式表理解成下面这样: 251 | 252 | ~~~css 253 | h1 { 254 | font: 18px Helvetica; 255 | color: purple background: aqua; 256 | } 257 | ~~~ 258 | 259 | 因为`background:`并不是`color`属性的合法值,而且`color`属性只能有一个关键字,因此用户代理会完全忽略`color`声明(包括`background: aqua`的部分)。你可能认为浏览器至少会把`h1`设置成紫色字体但没有水色背景,但是如果浏览器本身的实现是正确的话,你会连紫色的`h1`也看不到,它们会被设置成默认颜色(通常是黑色)和透明背景(默认)。声明`font: 18px Helvetica`将会依然生效,因为它是以一个分号正确结束的。 260 | 261 | _**虽然从技术上来讲,最后一条声明后面的分号并不是必需的,但通常为它加上分号是一个好的实践。首先,丢失分号是渲染错误的最常见的原因之一,遵循这个实践可以使你保持使用分号结束声明的良好习惯;其次,当你为样式规则追加一条声明的时候,不必担心前面的声明后面是否忘了插入分号;第三,如果你曾使用过像 Sass 这样的预处理器,通常尾部的分号对所有声明都是必需的。在每条声明后都跟随一个分号来避免上面的问题。**_ 262 | 263 | 分组声明和分组选择器一起使用,可以方便地保持样式表简洁、富有表现力和易于维护。 264 | 265 | ### 分组一切 266 | 267 | 选择器和声明都可以分组,在单条样式中使用这两种分组,可以使用很少的声明式定义非常复杂的样式。如果你要把一些复杂样式应用在文档的所有标题上,而且为他们应用相同的样式,应该怎么做呢?下面是做法: 268 | 269 | ~~~css 270 | h1, h2, h3, h4, h5, h6 {color: gray; background: white; padding: 0.5em; 271 | border: 1px solid black; font-family: Charcoal, sans-serif;} 272 | ~~~ 273 | 274 | 因为分组了选择器,右侧的规则会应用在列出的所有标题上;分组声明表明所有列出的样式都会被应用在左侧的选择器上。规则显示的结果如图 1-5。 275 | 276 | ![图1-5:分组选择器和规则](figure1-5.png) 277 | 278 | *图1-5:分组选择器和规则* 279 | 280 | 这种方案比下面的方案更好: 281 | 282 | ~~~css 283 | h1 {color: gray;} 284 | h2 {color: gray;} 285 | h3 {color: gray;} 286 | h4 {color: gray;} 287 | h5 {color: gray;} 288 | h6 {color: gray;} 289 | h1 {background: white;} 290 | h2 {background: white;} 291 | h3 {background: white;} 292 | ... 293 | ~~~ 294 | 295 | 等等还有许多行。你也**可以**像这样写出长长的样式,但我建议你不要这样做——编辑它们就像到处使用`style`属性一样无聊。 296 | 297 | 可以在选择器中加入更多的表达式,并以跨元素的方式应用样式。当然,要得到这么强大的东西需要付出一些工作,但这是值得的。 298 | 299 | ### 旧浏览器中的新元素 300 | 301 | 作为 HTML 的升级,HTML5 规范引入了新的元素。比新元素更早的浏览器不能识别它们。例如,IE9 以前的浏览器无法选择它们不支持的元素。解决办法是在 DOM 中创建元素,以此告知浏览器元素的存在。 302 | 303 | 例如,IE8 不能识别`
`元素,下面这行 JavaScript 代码告诉 IE8 `main`元素的存在: 304 | 305 | ~~~javascript 306 | document.createElement('main'); 307 | ~~~ 308 | 309 | 执行这行代码,旧版本的 IE 浏览器可以识别到这些元素,并允许选择它们以及为它们添加样式。 310 | 311 | ## 类和ID选择器 312 | 313 | 我们已经以各种方式组合使用了选择器和声明,但我们使用的选择器都非常简单。这些选择器只能用文档元素本身来选择,它们很好用,但有时你需要更专门的选择器。 314 | 315 | 除了原始的文档元素,还有**类选择器**和 **ID 选择器**,它们允许以独立于文档元素的方式分配样式。这些选择器可以单独使用,也可以与元素选择器结合使用。但是,它们只有在文档被正确标记的时候才能生效,因此使用它们通常需要做一些预想和规划。 316 | 317 | 例如,假设你正在起草一份讨论处理钚的方法的文件。 该文件包含关于安全处理这种危险物质的各种警告。 您希望每个警告都以粗体文本显示以便更突出,但你不知道这些警告将是哪些元素。 一些警告可能是整个段落,而其他警告可能是冗长列表中的单个项目或一小段文本。 因此,你不能使用任何种类的元素选择器定义规则。 假设你尝试这样写: 318 | 319 | ~~~css 320 | p {font-weight: bold;} 321 | ~~~ 322 | 323 | **所有的**段落都会被加粗,而不仅仅是包含警告的那些。你需要一种方法来选择仅包含警告的文本,或者更准确地说,只选择那些警告元素。怎么做呢?使用类选择器,把样式应用于文档中那些被用特定方式标记出来的部分,而无论是什么元素。 324 | 325 | ### 类选择器 326 | 327 | 忽略元素类型应用样式的最常用方式,是使用类选择器。但是在使用它们之前需要设置文档标记,以便选择器能够生效。添加`class`属性: 328 | 329 | ~~~html 330 |

When handling plutonium, care must be taken to avoid 331 | the formation of a critical mass.

332 |

With plutonium, the possibility of implosion is 333 | very real, and must be avoided at all costs. This can be accomplished 334 | by keeping the various masses separate.

335 | ~~~ 336 | 337 | 要把类选择器和一个元素联系起来,必须为`class`属性设置一个合适的值。在上面的代码中,一个值为`warning`的类被分配给两个元素:第一个段落和第二个段落里的`span`元素。 338 | 339 | 现在只需要一种方式把样式应用在这些元素上。在HTML文档中,可同`class`名称紧跟一个句点(.),并且可以与元素选择器一起使用: 340 | 341 | ~~~css 342 | .warning {font-weight: bold;} 343 | ~~~ 344 | 345 | 与前面所示的示例标记集合使用,这个简单规则的效果如图 1-6 所示。亦即,声明`font-weight: bold`会应用在每个(得益于隐含的通配选择器)`class`属性值为`warning`的元素上。 346 | 347 | _**通配选择器的符号是`*`,使用 ID、类、属性选择器、伪类选择器以及伪元素选择器等时,如果没有结合元素选择器,它们会隐式地包含通配选择器。**_ 348 | 349 | ![图1-6:使用类选择器](figure1-6.png) 350 | 351 | *图1-6:使用类选择器* 352 | 353 | 如你所见,类选择器直接通过元素`class`属性中的值来引用元素。引用始终以句点(.)开头,标记它是一个**类选择器**。句点把类选择器和与其组合在一起的其他部分区分开来(例如元素选择器)。假如当只有整个段落是警告时,才设置为粗体: 354 | 355 | ~~~css 356 | p.warning {font-weight: bold;} 357 | ~~~ 358 | 359 | 选择器现在只会匹配任何`class`属性值中包含单词`warning`的`p`元素,而其他类型的元素无论有没有设置`class`值都不会被选中。因为`span`元素不是段落,选择器不会匹配到它,因此它不会显示为粗体文字。 360 | 361 | 如果想为`span`元素分配不同的样式,可以使用选择符`span.warning`: 362 | 363 | ~~~css 364 | p.warning {font-weight: bold;} 365 | span.warning {font-style: italic;} 366 | ~~~ 367 | 368 | 这样,警告段落被设置为粗体,而警告`span`被设置为斜体。每个规则仅应用于特定的元素/类组合,而不会影响到其他元素。 369 | 370 | 另一种做法是使用一个一般的类选择器和一个特定元素的类选择器,来让样式更加有用,例如这样: 371 | 372 | ~~~css 373 | .warning {font-style: italic;} 374 | span.warning {font-weight: bold;} 375 | ~~~ 376 | 377 | 效果在图1-7中。 378 | 379 | ![图1-7:使用一般和特定选择器联合样式](figure1-7.png) 380 | 381 | *图1-7:使用一般和特定选择器联合样式* 382 | 383 | 这样设置,任何警告文字都被设置成斜体,但只有`class`属性值为`warning`的`span`元素中,文本既是粗体又是斜体。 384 | 385 | 请注意上例中的一般类选择器,它只包含一个类名和前面的句点,而没有任何元素名称,也没有通配选择器。如果你想选择具有某个类名的所有元素,省略通配选择器不会有任何影响。 386 | 387 | ### 多类 388 | 389 | 我们在前面看到了包含单个单词的`class`的属性值。在HTML中,使用空白分隔的单词列表可以作为单个`class`的值。例如,如果你想把某个特定元素标记为既是紧急的又是一个警告,可以这样写: 390 | 391 | ~~~html 392 |

When handling plutonium, care must be taken to 393 | avoid the formation of a critical mass.

394 |

With plutonium, the possibility of implosion is 395 | very real, and must be avoided at all costs. This can be accomplished 396 | by keeping the various masses separate.

397 | ~~~ 398 | 399 | (`class`值中)单词的顺序没有影响,写成`warning urgent`会产生完全相同的结果。 400 | 401 | 假如你想让所有`class`值为`warning`的元素加粗,把`class`值为`urgent`的设为斜体,而同时包含两个值的元素设置银色背景,写法是这样: 402 | 403 | ~~~css 404 | .warning {font-weight: bold;} 405 | .urgent {font-style: italic;} 406 | .warning.urgent {background: silver;} 407 | ~~~ 408 | 409 | 连接两个类选择器,可以选择那些只有同时具有两个类名的元素,无论类名的顺序如何。正如示例,HTML 代码中含有`class="urgent warning"`,但 CSS 选择器却写作`.warning.urgent`。这条规则依然可以把“When handling plutonium . . .”这段设置为银色背景,如图 1-8 所示,这是因为单词书写的顺序并不重要。(但这并不表示类名的顺序总是无关紧要的,我们将会在本书稍后涉及。) 410 | 411 | ![图1-8:使用多类名选择元素](figure1-8.png) 412 | *图1-8:使用多类名选择元素* 413 | 414 | 如果多类选择器里面包含一个不存在于空格分隔列表的类名,匹配将会失败。例如这个规则: 415 | 416 | ~~~css 417 | p.warning.help {background: red;} 418 | ~~~ 419 | 420 | 你可能期望这个选择器会匹配所有`class`中含有单词`warning`或`help`的`p`元素,然而实际上它不会匹配`class`属性中只有`warning`和`urgent`的`p`元素。它会匹配这样的元素: 421 | 422 | ~~~html 423 |

Help me!

424 | ~~~ 425 | 426 | ### ID选择器 427 | 428 | 从某些方面说,ID 选择器和类选择器类似,但它们有一些重要区别。首先,ID 选择器使用井号(`#`)开头,一条规则可能是这样的: 429 | 430 | ~~~css 431 | *#first-para {font-weight: bold;} 432 | ~~~ 433 | 434 | 这条规则为任意`id`属性值为`first-para`的元素设置文本粗体。 435 | 436 | 第二个区别是 ID 选择器(理所当然地)查找`id`属性而不是`class`属性的值。这是一个 ID 选择器生效的例子: 437 | 438 | ~~~css 439 | *#lead-para {font-weight: bold;} 440 | ~~~ 441 | 442 | ~~~html 443 |

This paragraph will be boldfaced.

444 |

This paragraph will NOT be bold.

445 | ~~~ 446 | 447 | 注意值`lead-para`可以关联给文档中的任意元素。在这个例子中,它只赋给了第一个段落,但是你可以同样赋给第二个、第三个段落。 448 | 449 | 和类选择器一样,ID 选择器中的通配选择符可以忽略。上例也可以写成这样: 450 | 451 | ~~~css 452 | #lead-para {font-weight: bold;} 453 | ~~~ 454 | 455 | 效果是一样的。 456 | 457 | 另一个与类选择器相似的地方是,ID 选择器也可以独立于元素类型。可能有些场景下你知道有一个确定 ID 值会出现在文档中,但不知道会出现在哪个元素上(如在前面的钚处理警告中),因此需要声明独立的ID选择器。例如,在任意给定的文档中,有一个元素的 ID 值是`mostImportant`,但不知道这个元素是一个段落、引用、列表还是段落头,只知道这个值会出现在每个文档中的某个随机的元素上,而且在每个文档中仅出现一次。在这种情况下,规则可以这样写: 458 | 459 | ~~~css 460 | #mostImportant {color: red; background: yellow;} 461 | ~~~ 462 | 463 | 这条规则会匹配下面的每一个元素(正如上面强调的,因为它们有相同的 ID 值,所以任意两个*不应该*同时出现在一个文档中): 464 | 465 | ~~~html 466 |

This is important!

467 | This is important! 468 |
    This is important!
469 | ~~~ 470 | 471 | ### 决定使用Class还是ID 472 | 473 | 类可以分配给任意多的元素,类名`warning`可以分配给一个`p`元素或者一个`span`元素,或者更多其他元素。另一方面,ID在一个 HTML 文档中使用且仅使用一次。因此如果有了一个`id`值为`lead-para`的元素,该文档中的其他元素都不能有`lead-para`的`id`值。 474 | 475 | _**在实际中,浏览器并不总会检查 HTML 中 ID 的唯一性。如果你为多个元素设置了相同的 ID 属性值,它们可能都会被设置为相同的样式。这是不正确的实现,但这种情况很普遍。在一个文档中存在多个 ID 值相同的元素还会导致 DOM 脚本的问题,因为像`getElementById()`这样的函数依赖于文档中只存在一个 ID 为特定值的元素。**_ 476 | 477 | 与类选择器不同,ID 选择器不能联合使用,因为 ID 属性不允许使用空白分隔的单词列表。 478 | 479 | `class`和`id`名称的另一个区别是,当决定某个元素应该应用哪个样式时,ID 有更高的权重。这点将在后面详细讨论。 480 | 481 | 还要注意类和 ID 可能是大小写敏感的,这取决于文档的语言。HTML 语言把类和 ID 定义为大小写敏感的,因此类和 ID 选择器的大小写要和文档中的匹配。在下面的 CSS 和 HTML 中,元素文字不会被设置为粗体: 482 | 483 | ~~~css 484 | p.criticalInfo {font-weight: bold;} 485 | ~~~ 486 | 487 | ~~~html 488 |

Don't look down.

489 | ~~~ 490 | 491 | 因为字母`i`的大小写不一致,选择器不会匹配元素。 492 | 493 | 从纯语法层次来说,点-类标记(例如:`.warning`)不能保证在 XML 文档中生效。在撰写本文时,点-类标记在 HTML、SVG和 MathML 中有效,它可能在未来被更多语言支持,但这要取决于语言本身的规范。哈希-ID 标记(例如:#lead)在所有强制属性唯一性的语言中都有效。唯一性可以强制使用名为`id`的属性,或者任何其他属性,只要在文档中属性内容被定义为唯一的即可。 494 | 495 | ## 属性选择器 496 | 497 | 当你使用类和 ID 选择器时,实际上是在选择属性的值。类选择器和 ID 选择器专用于 HTML、XHTML、SVG和 MathML 文档(到撰写本文时),但在其它的标记语言中,这两个选择器可能是不可用的(属性可能不存在)。因此,CSS2 引入了**属性选择器**,使用元素的任意属性和值来选择元素。属性选择器有四种基本类型:简单属性选择器、准确属性值选择器、部分匹配属性选择器和头值属性选择器。 498 | 499 | ### 简单属性选择器 500 | 501 | 如果想选择具有某个特定属性的元素,而无论属性的值是什么,可以使用**简单属性选择器**。例如,选择所有具备`class`属性的`h1`元素,然后将其文本设置为银色: 502 | 503 | ~~~css 504 | h1[class] {color: silver;} 505 | ~~~ 506 | 507 | 对如下代码: 508 | 509 | ~~~html 510 |

Hello

511 |

Serenity

512 |

Fooling

513 | ~~~ 514 | 515 | 将得到如图1-9的结果: 516 | 517 | ![图1-9:使用属性选择元素](figure1-9.png) 518 | 519 | *图1-9:使用属性选择元素* 520 | 521 | 这种策略对 XML 文档非常有用,因为 XML 语言的元素经常含有表示特定意义的属性名。例如可以想象一种描述太阳系行星的 XML 语言(可以叫它 PlanetML)。如果想要选择所有包含`moons`属性的`pml-planet`元素,把文本设置成粗体,用来突出有月亮的行星,可以这样写: 522 | 523 | ~~~css 524 | pml-planet[moons] {font-weight: bold;} 525 | ~~~ 526 | 527 | 第二个和第三个元素将会被设置成粗体,第一个则不会: 528 | 529 | ~~~html 530 | Venus 531 | Earth 532 | Mars 533 | ~~~ 534 | 535 | 在HTML中可以用一些创新的方式使用这个特性。例如可以为所有包含`alt`属性的图片设置样式,因此突出形式规范的图片: 536 | 537 | ~~~css 538 | img[alt] {border: 3px solid red;} 539 | ~~~ 540 | 541 | (这个特殊例子更适用于检查而不是设计目的,用来查看图片是否被设置了完全规范的标记。) 542 | 543 | 大部分浏览器在鼠标放到元素上的时候,会显示元素的`title`属性值,称为“tool tip”。如果想把所有包含`title`信息的元素粗体显示,可以这样: 544 | 545 | ~~~css 546 | *[title] {font-weight: bold;} 547 | ~~~ 548 | 549 | 相似地,可以选择那些包含`href`属性的锚点(`a`)元素,以此为超链接而不是所有锚点元素添加样式。 550 | 551 | 也可以基于多个属性选择元素,只需简单地并列多个属性选择器即可。例如,把包含`href`和`title`属性的HTML超链接设置为粗体: 552 | 553 | ~~~css 554 | a[href][title] {font-weight: bold;} 555 | ~~~ 556 | 557 | 第一个链接会设置为粗体,第二个和第三个不会: 558 | 559 | ~~~html 560 | W3C
561 | Standards Info
562 | dead.letter 563 | ~~~ 564 | 565 | ### 基于准确属性值选择 566 | 567 | 可以进一步缩小选择器范围选择那些某个属性为某个确定值的元素。例如,把指向服务器上某个特定文档的链接设置为粗体: 568 | 569 | ~~~css 570 | a[href="http://www.css-discuss.org/about.html"] {font-weight: bold;} 571 | ~~~ 572 | 573 | 所有`href`属性值**准确地**是`http://www.css-discuss.org/about.html`的`a`元素会被设置为粗体。任何修改,即使去掉了`www.`,也会造成无法匹配。 574 | 575 | 任何属性和值的联合都可以定义在任何元素上,然而,如果这个联合没有(准确地)出现在文档中,选择器不会匹配任何东西。XML 语言再次得益于这种方式来设置属性。回到 PlantML 的例子,如果想选择那些`moons`属性值为`1`的`planet`元素: 576 | 577 | ~~~css 578 | planet[moons="1"] {font-weight: bold;} 579 | ~~~ 580 | 581 | 第二个元素的文本将会被设置为粗体,第一个和第三个不会: 582 | 583 | ~~~html 584 | Venus 585 | Earth 586 | Mars 587 | ~~~ 588 | 589 | 与属性选择一样,使用多个元素-值选择器也可以选择单个文档。例如,将`href`属性值为`http://www.w3.org/`且`title`属性值为`W3C Home`的 HTML 超链接文本设置为两倍尺寸: 590 | 591 | ~~~css 592 | a[href="http://www.w3.org/"][title="W3C Home"] {font-size: 200%;} 593 | ~~~ 594 | 595 | 第一个元素会被设置为双倍尺寸字体,第二个和第三个不会: 596 | 597 | ~~~html 598 | W3C
599 | Standards Info
601 | dead.link 602 | ~~~ 603 | 604 | 结果如图 1-10。 605 | 606 | ![图1-10:使用属性和值选择元素](figure1-10.png) 607 | 608 | *图1-10:使用属性和值选择元素* 609 | 610 | 这种方式需要属性值的**精确**匹配。属性值为多个空白分隔的值列表时,匹配可能会因多个值的顺序不同而产生问题(如 HTML 的属性 `class`)。例如下面的代码片段: 611 | 612 | ~~~html 613 | Mercury 614 | ~~~ 615 | 616 | 匹配这个元素的唯一方式是使用准确的属性值: 617 | 618 | ~~~css 619 | planet[type="barren rocky"] {font-weight: bold;} 620 | ~~~ 621 | 622 | 如果使用`planet[type="barren"]`,规则不会匹配是这个示例。即使是HTML中的`class`属性,也会出现这种情况。例如: 623 | 624 | ~~~html 625 |

When handling plutonium, care must be taken to 626 | avoid the formation of a critical mass.

627 | ~~~ 628 | 629 | 要基于准确属性值选择元素,应该这样: 630 | 631 | ~~~css 632 | p[class="urgent warning"] {font-weight: bold;} 633 | ~~~ 634 | 635 | 我们将在下节看到,这和之前介绍的点-类选择是**不**等同的。这条规则将会选择`class`属性值**精确**地是`urgent warning`的所有`p`元素,单词以相同的顺序,并且中间以单个空格隔开。它实际上是一个精确字符串匹配。 636 | 637 | 同样地,ID 选择器和使用`id`属性的属性选择器也不是恰好相同的。换句话说,在`h1#page-title`和`h1[id="page-title"]`之间,存在着细微但很重要的区别。这种区别将在章节“特度”解释。 638 | 639 | ### 基于部分属性值选择 640 | 641 | 你可能想基于属性值的一部分而不是整个值来选择元素,这种情况下 CSS 提供了一些选择,匹配属性值中的子串。它们总结在表格 1-1 中。 642 | 643 | *表格1-1:子串匹配属性选择器* 644 | 645 | |类型|描述| 646 | |:----|:-----| 647 | |`[foo~="bar"]`|选择所有带有`foo`属性、且`foo`属性被空白分隔的单词列表中含有单词`bar`的元素。| 648 | |`[foo*="bar"]`|选择所有带有`foo`属性、且`foo`属性值中含有子串`bar`的元素。| 649 | |`[foo^="bar"]`|选择所有带有`foo`属性、且`foo`属性值以`bar`开头的元素。| 650 | |`[foo$="bar"]`|选择所有带有`foo`属性、且`foo`属性值以`bar`结束的元素。| 651 | |`[foo|="bar"]`|选择所有带有`foo`属性、且`foo`属性值以`bar`开头后接一个短线(`U+002D`)或者属性值是`bar`的元素。| 652 | 653 | ### 特定的属性选择器 654 | 655 | 基于部分属性值的选择器中的最后一个,展示它的用法比描述它更简单。看下面的规则: 656 | 657 | ~~~css 658 | *[lang|="en"] {color: white;} 659 | ~~~ 660 | 661 | 这条规则会选择任何`lang`属性等于`en`或者以`en-`开头的元素。因此,下面的示例中前三个标签会被选中,而后两个则不会: 662 | 663 | ~~~html 664 |

Hello!

665 |

Greetings!

666 |
G'day!
667 |

Bonjour!

668 |

Jrooana!

669 | ~~~ 670 | 671 | 一般来说,`[att|="val"]`的格式可以用于任何属性和属性值。如果HTML文档中有一系列图片,文件名都像**“figure-1.gif”**和**“figure-3.jpg”**这样,可以使用这样的选择器匹配所有这样的图片: 672 | 673 | ~~~css 674 | img[src|="figure"] {border: 1px solid gray;} 675 | ~~~ 676 | 677 | 如果你正在创建一个 CSS 框架或模式库,不必创建许多繁琐的类:`"btn btn-small btn-arrow btn-active"`,你可以声明`"btn-small-arrow-active"`,然后这样匹配元素的类: 678 | 679 | ~~~css 680 | *[class|="btn"] { border-radius: 5px;} 681 | ~~~ 682 | 683 | ~~~html 684 | 685 | ~~~ 686 | 687 | 这个属性选择器最常用的场景是用来匹配语言值,我们将在"`:lang`伪类"章节看到。 688 | 689 | #### 匹配空白分隔的列表中的一个单词 690 | 691 | 任何使用空白分隔单词列表的属性,都可以基于这些单词中的任意一个选择元素。HTML 中最经典的例子是`class`属性,该属性可以使用一或多个单词作为值。看这个常用例子: 692 | 693 | ~~~html 694 |

When handling plutonium, care must be taken to 695 | avoid the formation of a critical mass.

696 | ~~~ 697 | 698 | 如果要选择`class`属性中包含单词`warning`的元素,可以使用这样的属性选择器: 699 | 700 | ~~~css 701 | p[class~="warning"] {font-weight: bold;} 702 | ~~~ 703 | 704 | 注意选择器中的波浪线(~),这是基于属性值中分离单词进行选择的关键字。如果忽略了波浪线,选择器就变成了前面讨论过的精确值匹配的属性选择器。 705 | 706 | 这个选择器跟“决定使用Class还是ID”中的点-类选择器是等同的。也就是说,用于 HTML 文档时,`p.warning`和`p[class~="warning"]`是相等同的。这是前面提到过的“PlanetML”标记例子的一个 HTML 版本: 707 | 708 | ~~~html 709 | Mercury 710 | Venus 711 | Earth 712 | ~~~ 713 | 714 | 要把所有`class`属性值中包含单词`barren`的元素设置为斜体: 715 | 716 | ~~~css 717 | span[class~="barren"] {font-style: italic;} 718 | ~~~ 719 | 720 | 这个选择器将会匹配例子中的前两个元素并把它们设置为斜体。这和使用`span.barren {font-style: italic;}`是一样的效果。 721 | 722 | ![图1-11:使用部分属性值选择元素](figure1-11.png) 723 | 724 | *图1-11:使用部分属性值选择元素* 725 | 726 | 既然效果相同,为什么还要在HTML中使用波浪线-等号属性选择器呢?因为它可被用于任何属性,而不仅仅是`class`。例如:一个文档中包含许多图片,其中一部分是图表,你可以使用匹配部分属性值的选择器选择`title`属性的文字,来选中那些是图表的图片: 727 | 728 | ~~~css 729 | img[title~="Figure"] {border: 1px solid gray;} 730 | ~~~ 731 | 732 | 这条规则会选择所有`title`文字中包含`Figure`的单词。因此,如果所有的图表的`title`中都有像“Figure 4. A bald- headed elder statesman,”这样的文字,这条规则会匹配所有的图表。同样的,选择器`img[title~="Figure"]`也会匹配`title`属性值是“How to Figure Out Who’s in Charge.”这样内容的图片。所有没有`title`属性的图片,或者`title`值中不包含单词“Figure”的图片,都不会被匹配。 733 | 734 | #### 匹配属性值中的子串 735 | 736 | 有时需要匹配属性值的一部分,但并不是空格分隔的单词。这种情况下,可以使用`[att*="val"]`的形式匹配属性值中的任何位置。例如:下面的CSS匹配任何`class`属性值中包含子串`cloud`的`span`元素,所以两个“cloudy”的行星都会被匹配,如图1-12。 737 | 738 | ~~~css 739 | span[class*="cloud"] {font-style: italic;} 740 | ~~~ 741 | 742 | ~~~html 743 | Mercury 744 | Venus 745 | Earth 746 | ~~~ 747 | 748 | ![图1-12:基于属性值内子串选择元素](figure1-12.png) 749 | 750 | *图1-12:基于属性值内子串选择元素* 751 | 752 | 这种用法有许多有用的场景,例如为所有到O'Reilly Media网页的链接添加特殊样式。避免给它们设置类名并基于类添加样式,可以简单地使用下面的规则: 753 | 754 | ~~~css 755 | a[href*="oreilly.com"] {font-weight: bold;} 756 | ~~~ 757 | 758 | 选择不限于使用`class`和`href`属性,任何属性都可以。`title`、`alt`、`src`、`id`……可以基于任何属性值的子串添加样式。下面的规则选择所有源文件 URL 中包含字符串“space”的图片: 759 | 760 | ~~~css 761 | img[src*="space"] {border: 5px solid red;} 762 | ~~~ 763 | 764 | 类似地,下面的规则关注有标题的`input`元素,标题中包含子串`format`: 765 | 766 | ~~~css 767 | input[title*="format"] {background-color: #dedede;} 768 | ~~~ 769 | 770 | ~~~html 771 | 774 | ~~~ 775 | 776 | 属性子串匹配选择器常用来匹配模式库中的类名。在前面的例子中,我们可以匹配以`btn`开始后跟一个短线,并且包含前面有短线的子串`arrow`的类名: 777 | 778 | ~~~css 779 | *[class|="btn"][class*="-arrow"]:after { content: "▼";} 780 | ~~~ 781 | 782 | ~~~html 783 | 784 | ~~~ 785 | 786 | 这种匹配方式是精确匹配——如果选择器中包含空白,属性值中必须包含空白才能匹配。只有当依赖的文档语言要求区分大小写时,属性名和值才必须区分大小写。类名、标题和 ID 值都是大小写敏感的,但 HTML 的属性关键字值,比如`input`元素的类型,不区分大小写: 787 | 788 | ~~~css 789 | input[type="CHeckBoX"] {margin-right: 10px;} 790 | ~~~ 791 | 792 | ~~~html 793 | 794 | ~~~ 795 | 796 | #### 匹配属性值开头的子串 797 | 798 | 当需要基于属性值开头的子串选择元素时,可以使用属性选择器模式`[attr^="val"]`。这个匹配模式在给不同类别的链接设置样式时特别有用,如图 1-13 所示: 799 | 800 | ~~~css 801 | a[href^="https:"] {font-weight: bold;} 802 | a[href^="mailto:"] {font-style: italic;} 803 | ~~~ 804 | 805 | ![图1-13:基于属性开头的子串选择元素](figure1-13.png) 806 | 807 | *图1-13:基于属性开头的子串选择元素* 808 | 809 | 另一个使用场景是为文档中所有内容是说明的图片添加样式——假定所有的说明图的`alt`属性的文字都以“Figure 5”这样的模式开头——则可以使用这种方式选择这些图片: 810 | 811 | ~~~css 812 | img[alt^="Figure"] {border: 2px solid gray; display: block; margin: 2em auto;} 813 | ~~~ 814 | 815 | 潜藏的问题是,**任何**`alt`属性值以“Figure”开头的`img`标签都会被选择,而无论它是不是一个说明图。显然,是否产生这个问题是由文档决定的(而不是选择器)。 816 | 817 | 另一个使用场景是选择所有周一的日程。这种场景中,我们约定所有的事件都有个`title`属性,它以这样的日期格式`Monday,March 5th,2012`开头。选择它们只需要简单地使用`[title^="Monday"]`。 818 | 819 | #### 匹配属性值结尾的字串 820 | 821 | 与开头子串匹配相对应的是结尾子串匹配,使用选择器模式`[att$="val"]`。最常见的使用场景是基于链接的资源类型添加样式,例如图1-14所示,为指向 PDF 文档的链接添加特定样式。 822 | 823 | ~~~css 824 | a[href$=".pdf"] {font-weight: bold;} 825 | ~~~ 826 | 827 | ![图1-14:基于属性结尾的子串选择元素](figure1-14.png) 828 | 829 | *图1-14:基于属性结尾的子串选择元素* 830 | 831 | 类似地,可以(无论因何)基于格式选择图片: 832 | 833 | ~~~css 834 | img[src$=".gif"] {...} 835 | img[src$=".jpg"] {...} 836 | img[src$=".png"] {...} 837 | ~~~ 838 | 839 | 上一节中日程的例子,可以基于给定的年份选择所有事件,使用一个类似这样的选择器`[title$="2015"]`(`title`属性以年份结尾)。 840 | 841 | _**你可能注意到了,属性选择器中的所有属性值都用了引号包围。当属性值包含任何特殊字符、以短线或数字开头、或其他非法标识符时,需要使用引号把它标记成字符串。为了安全,建议在任何情况下都为属性选择器中的属性值添加引号,尽管只有非法标识符导致它需要被标记成字符串的时候引号才是必需的。**_ 842 | 843 | ### 忽略大小写标识符 844 | 845 | CSS Selectors level 4 为属性选择器引入了忽略大小写选项。在中括号关闭之前使用`i`允许选择器匹配属性值的时候忽略大小写,无视文档语言的规则。 846 | 847 | 例如,你想选择所有指向 PDF 文档的链接,但并不确定它们以`.pdf`、`.PDF`还是`.Pdf`结束,可以这样: 848 | 849 | ~~~css 850 | a[href$='.PDF' i] 851 | ~~~ 852 | 853 | 添加一个小小的`i`表示选择器匹配任何`href`属性以`.pdf`结束的`a`元素,无论其中是否包含大写的`P`、`D`或`F`。 854 | 855 | 忽略大小写选项适用于前面涉及的所有属性选择器,但要注意它只用于属性选择器的**值**,而不能用于属性名本身。因此,在大小写敏感的语言中,`planet[type*="rock" i]`可以匹配下面所有的元素: 856 | 857 | ~~~html 858 | Mercury 859 | Venus 860 | Earth 861 | ~~~ 862 | 863 | 但不能匹配下面的元素,因为属性`TYPE`不匹配`type`: 864 | 865 | ~~~html 866 | Mars 867 | ~~~ 868 | 869 | 再次说明,是否在元素和属性语法中强制区分大小写是由语言决定的,XHTML 是这样的语言。在大小写不敏感的语言中没有这样的问题,例如 HTML5。 870 | 871 | _**至 2017 年底,Opera Mini、Android 浏览器和 Edge 不支持此能力。**_ 872 | 873 | ## 使用文档结构 874 | 875 | 如前面所说,CSS 之强大在于它利用文档结构决定(元素的)样式和样式作用于元素的方式。结构确实在样式作用于文档时扮演了非常重要的角色,在继续讨论更强大的选择形式之前,我们先来讨论结构。 876 | 877 | ### 理解父-子关系 878 | 879 | 为了理解选择器和文档之间的关系,我们要再次回顾文档结构是如何组织的,看下面这个非常简单的HTML文档: 880 | 881 | ~~~html 882 | 883 | 884 | 885 | Meerkat Central 886 | 887 |

Meerkat Central

888 |

889 | Welcome to Meerkat Central, the best meerkat web site on the entire Internet! 890 |

891 |
    892 |
  • We offer: 893 |
      894 |
    • Detailed information on how to adopt a meerkat
    • 895 |
    • Tips for living with a meerkat
    • 896 |
    • Fun things to do with a meerkat, including: 897 |
        898 |
      1. Playing fetch
      2. 899 |
      3. Digging for food
      4. 900 |
      5. Hide and seek
      6. 901 |
      902 |
    • 903 |
    904 |
  • 905 |
  • ...and so much more!
  • 906 |
907 |

Questions? Contact us!

908 | 909 | 910 | ~~~ 911 | 912 | CSS 的能力很大程度基于于元素的**父-子关系**。HTML 文档(事实上绝大部分结构化文档)基于元素层级结构,构成文档的“树状”视图(见图1-15)。在这种层级结构中,每个元素都处在整个文档结构中的某个适当位置上,每个元素都是其他元素的**父**或者**子**,常常既是父又是子。 913 | 914 | ![图1-15:文档树结构](figure1-15.png) 915 | 916 | *图1-15:文档树结构* 917 | 918 | 在文档层级结构中,如果一个元素在另一个元素的紧邻的上方,就被称作那个元素的父元素。例如,在图1-15中,第一个`p`元素是`em`和`strong`元素的父元素,同时`strong`是一个锚点(`a`)元素的父元素,这个`a`元素又是另一个`em`元素的父元素。反过来,如果在文档层级中,一个元素在另一个元素的紧邻的下方,就被称作那个元素的子元素。因此,图1-15中的锚点元素是`strong`元素的子元素,`strong`元素又是`p`元素的子元素,等等。 919 | 920 | “父”和“子”是**祖先**和**后代**的特例。它们的区别是:在树状视图中,如果一个元素在另一个元素上面一级,那么它们是父-子关系。如果一个元素到另一个元素的路径有两级或者更多,那么它们是祖先-后代关系,但不是父-子关系。(当然,子也是后代,同时父也是祖先。)在图 1-15 中,第一个`ul`元素是两个`li`元素的父元素,同时也是它的`li`元素所有后代元素的祖先元素,直到嵌套路径最深的`li`元素。 921 | 922 | 同时,在图1-15中,存在一个锚点元素既是`strong`元素的子元素,又是`p`、`body`和`html`元素的后代元素。`body`元素是浏览器默认显示的所有元素的祖先元素,`html`是整个文档中所有其他元素的祖先元素。因此在 HTML 或 XHTML 文档中,`html`元素也被叫做**根元素**。 923 | 924 | ### 后代选择器 925 | 926 | 理解文档模型的第一个用处是可以定义**后代选择器**(也叫做**上下文选择器**)。定义后代选择器可以创建只作用于特定结构的规则。例如,如果想要只为那些是`h1`元素的后代的`em`元素设置样式。你可以为`h1`中的`em`元素添加一个`class`属性,但这样做会跟使用`font`标签一样耗费时间。很明显,声明一个只匹配`h1`元素中的`em`元素的规则更加方便。 927 | 928 | 实现这个规则,可以这样写: 929 | 930 | ~~~css 931 | h1 em {color: gray;} 932 | ~~~ 933 | 934 | 这条规则会把所有是`h1`元素后代的`em`元素中的文本设置为灰色。其他的`em`文本,例如在段落(`p`)或引用(`blackquote`)中的`em`元素,不会被这条规则选择。见图1-16。 935 | 936 | ![图1-16:基于上下文选择元素](figure1-16.png) 937 | 938 | *图1-16:基于上下文选择元素* 939 | 940 | 在后代选择器中,选择器由两个或更多空白分隔的选择器组成。选择器之间的空格是一个**组合器**的例子。每个空格组合器都可以被译作“在……中”、“是……的一部分”或“是……的后代”,前提是选择器从右向左读。因此,`h1 em`可以被译作“把样式作用于任何`em`元素,如果它是`h1`元素的后代”。(如果选择器从左向右读,则是:“选择任何`h1`,如果它包含一个`em`元素,规则将会作用于它包含的`em`”)。 941 | 942 | 可以使用不止两个选择器,例如: 943 | 944 | ~~~css 945 | ul ol ul em {color: gray;} 946 | ~~~ 947 | 948 | 在这种情况下,任何`em`文本,如果这个`em`在一个`ul`中,同时`ul`在一个`ol`中,而`ol`又在另一个`ul`中,这个`em`会被设置为灰色,如1-17所示。这是一条非常具体的选择规则。 949 | 950 | ![图1-17:一个非常具体的后代选择器](figure1-17.png) 951 | 952 | *图1-17:一个非常具体的后代选择器* 953 | 954 | 后代选择器非常有用,它使得 HTML 中(至少是不使用怪异的`font`标签时)办不到的事情变成可能。一个常见的场景是:如果文档中有一个侧边栏和一个主区域,侧边栏的背景是蓝色,而主区域的背景是白色,它们都包含链接。不能把链接设置为蓝色,因为如果这样的话,侧边栏中的链接就看不到了。 955 | 956 | 解决方法是:后代选择器。在这种情况下,给包含侧边栏的元素(一般是一个`div`)添加一个`class`值`sidebar`,把主区域的`class`命名为`main`,然后使用如下样式: 957 | 958 | ~~~css 959 | .sidebar {background: blue;} 960 | .main {background: white;} 961 | .sidebar a:link {color: white;} 962 | .main a:link {color: blue;} 963 | ~~~ 964 | 965 | 图1-18显示了样式的结果。 966 | 967 | ![图1-18:使用后代选择器为同一类型的元素添加不同的样式](figure1-18.png) 968 | 969 | *图1-18:使用后代选择器为同一类型的元素添加不同的样式* 970 | 971 | _**`:link`选择那些尚未被访问过的资源链接,我们将在“超链接伪类”中详细讨论。**_ 972 | 973 | 另一个例子是:如果要把所有在`blockquote`和`p`中的`b`元素文本设置为灰色: 974 | 975 | ~~~css 976 | blockquote b, p b {color: gray;} 977 | ~~~ 978 | 979 | 这条样式的结果是在段落或引用段落中的`b`元素中的文本显示为灰色。 980 | 981 | 后代选择器的一个容易被忽略的地方是,元素和后代元素之间可以间隔无限代其他元素。例如,如果使用规则`ul em`,将会选择`ul`元素后代中的任何`em`元素,无论`em`元素嵌套多么深。因此,对下面的代码,`ul em`会匹配到其中的`em`元素。 982 | 983 | ~~~html 984 |
    985 |
  • List item 1 986 |
      987 |
    1. List item 1-1
    2. 988 |
    3. List item 1-2
    4. 989 |
    5. List item 1-3 990 |
        991 |
      1. List item 1-3-1
      2. 992 |
      3. List item 1-3-2
      4. 993 |
      5. List item 1-3-3
      6. 994 |
      995 |
    6. 996 |
    7. List item 1-4
    8. 997 |
    998 |
  • 999 |
1000 | ~~~ 1001 | 1002 | 后代选择器的另一个更微妙的地方是,它没有接近程度的概念。换句话说,文档树中两个元素的紧密程度与是否应用规则无关。这将会在考虑特异性(特度,在后面讨论)和元素规则之间的相互抵消时产生影响。 1003 | 1004 | 例如,考虑下面的代码(包含我们将会在本章“否定伪类”中讨论的选择器): 1005 | 1006 | ~~~html 1007 | div:not(.help) span {color: gray;} 1008 | div.help span {color: red;} 1009 | 1010 |
1011 |
1012 | This text contains a span element within. 1013 |
1014 |
1015 | ~~~ 1016 | 1017 | 第一条规则表示“任何`class`中不包含单词`help`的`div`元素中的`span`元素被设置为灰色”,第二条规则表示“任何`class`中包含单词`help`的`div`元素中的`span`元素被设置为红色”。对示例中的HTML代码来说,两条规则都会被作用于`span`元素。 1018 | 1019 | 因为两条规则有相同的权重,且“红色”规则被写在后面,`span`会被设置为红色。虽然`div class="aside"`比`div class="help"`相比,与`span`元素更“紧密”,但实际上这种紧密程度与规则的选择毫不相关。亦即:后代选择器没有紧密程度的概念。两条规则都匹配了元素,只有一种颜色可以生效,根据CSS的工作方式,红色“胜利”了。(下一章讨论) 1020 | 1021 | ### 选择子元素 1022 | 1023 | 有时,我们并不想选择全部的后代元素,而是把选择范围控制在元素的子级,例如选择一个是`h1`元素的子元素(而不是任意后代元素)的`strong`元素,这种情况下,可以使用子元素组合器,它是一个大于号(`>`): 1024 | 1025 | ~~~css 1026 | h1 > strong {color: red;} 1027 | ~~~ 1028 | 1029 | 这条规则将会把下面的第一个`h1`元素中的`strong`元素设置为红色,第二个`h1`元素中的`strong`元素则不会被设置为红色。 1030 | 1031 | ~~~html 1032 |

This is very important.

1033 |

This is really very important.

1034 | ~~~ 1035 | 1036 | 从右往左读,选择器`h1 > strong`可以译作“选择任何`strong`元素,如果它是一个`h1`元素的子元素”。子元素组合器两边可以添加空格, 你可以根据自己的爱好添加或省略空格,`h1 > strong`、`h1> strong`和`h1>strong`是完全等价的。 1037 | 1038 | 观察文档的树状结构视图,子元素选择器把匹配限制在直接连接的元素上。图1-19显示了部分文档树。 1039 | 1040 | ![图1-19:一个文档树片段](figure1-19.png) 1041 | 1042 | *图1-19:一个文档树片段* 1043 | 1044 | 在这文档树片段中,可以很清楚的观察到父-子关系。例如,`a`元素是`strong`元素的父元素,同时是`p`元素的子元素。在这个片段中,可以使用`p > a`和`a > strong`选择元素,但无法使用`p > strong`选择元素,因为`strong`是`p`的后代元素但不是子元素。 1045 | 1046 | 在同一个选择器中可以结合使用后代选择器和子元素原则器。`table.summary td > p`选择是`td`元素子元素的`p`元素,同时这个`td`元素需要是一个`class`属性值包含`summary`的`table`元素的后代元素。 1047 | 1048 | ### 选择相邻兄弟元素 1049 | 1050 | 假如想要为一个紧跟着标题的段落设置样式,或者给一个紧跟着段落的列表添加一个边距,可以使用**相邻兄弟组合器**来选择在同一个父级元素下紧跟着另一个元素的元素,组合器使用加号(`+`)。就像子级选择器一样,这个符号也可以在两边添加或省略空格。 1051 | 1052 | 移除一个紧跟`h1`元素的段落的上边距: 1053 | 1054 | ~~~css 1055 | h1 + p {margin-top: 0;} 1056 | ~~~ 1057 | 1058 | 选择器读作:“选择任何紧跟在`h1`元素后面的`p`元素”。 1059 | 1060 | 看图1-20的文档树片段,更清晰地观察这个选择器是如何生效的: 1061 | 1062 | ![图1-20:一个文档树片段](figure1-20.png) 1063 | 1064 | *图1-20:一个文档树片段* 1065 | 1066 | 在这个片段中有两个列表都是`div`元素的后代,一个是有序列表,另一个是无序列表,每个都包含三个列表项。两个列表互为相邻兄弟,每个列表中的列表项也互为相邻兄弟,但第一个列表中的项与第二个列表中的列**不是**相邻兄弟,因为它们没有共同的父元素。(它们最多是表兄弟元素,但CSS没有表兄弟元素选择器。) 1067 | 1068 | 选择后面的两个相邻兄弟只需要一个组合器符号,如果写作`li + li {font-weight: bold;}`,只有每个列表中的第二项和第三项会被设置为粗体,样式不会对第一项生效。见图1-21. 1069 | 1070 | ![图1-21:选择相邻兄弟元素](figure1-21.png) 1071 | 1072 | *图1-21:选择相邻兄弟元素* 1073 | 1074 | CSS的正确性依赖于两个元素的“代码顺序“。在上面的例子中,一个`ol`元素后面紧跟着一个`ul`元素,因此可以使用`ol + ul`选择第二个(`ul`)元素,但不能选择第一个(`ol`)元素。如果想使`ul + ol`匹配,需要一个`ol`元素紧跟在一个`ul`元素后面。 1075 | 1076 | 需要记住,两个元素之间的文本内容**不会**影响相邻元素组合器。下面的代码片段,树视图与图1-19是一样的: 1077 | 1078 | ~~~html 1079 |
1080 |
    1081 |
  1. List item 1
  2. 1082 |
  3. List item 1
  4. 1083 |
  5. List item 1
  6. 1084 |
1085 | This is some text that is part of the 'div'. 1086 |
    1087 |
  • A list item
  • 1088 |
  • Another list item
  • 1089 |
  • Yet another list item
  • 1090 |
1091 |
1092 | ~~~ 1093 | 1094 | 尽管两个列表之间有文本内容,选择器`ol + ul`依然会匹配第二个列表。因为文本并不包含一个兄弟元素,而是属于父元素`div`的一部分。如果把文本内容用一个段落元素(`p`)包起来,`ol + ul`匹配第二个列表的行为将会被终止。要匹配第二个列表,需要用`ol + p + ul`这样的选择器。 1095 | 1096 | 相邻兄弟组合器可以与其他组合器连接使用,例如: 1097 | 1098 | ~~~css 1099 | html > body table + ul{margin-top: 1.5em;} 1100 | ~~~ 1101 | 1102 | 这个选择器是指:“选择任何紧跟`table`元素的兄弟`ul`元素,同时这个`table`元素是一个`body`元素的后代,而`body`元素是一个`html`的子元素。” 1103 | 1104 | 和所有组合器一样,相邻兄弟选择器可以用于很复杂的选择器中,如`div#content h1 + div ol`。这个选择器是:“选择任何是`div`元素后代的`ol`元素,同时这个`div`元素是一个`h1`元素的紧邻兄弟元素,而这个`h1`元素是一个`id`属性值为`content`的`div`元素的子元素。” 1105 | 1106 | ### 选择跟随兄弟元素 1107 | 1108 | Selectors Level 3 引入了一个新的兄弟组合器叫做**一般兄弟选择器**。这个组合器允许选择同一个父元素下,跟随(不一定是紧跟随)在某个元素后面的所有元素,使用波浪线符号(`~`)。 1109 | 1110 | 如下例,为同一个父元素下跟随在一个`h2`元素后面的任何`ol`元素设置斜体,可以写作`h2 ~ ol {font-style: italic;}`。两个`ol`元素不必都是紧邻兄弟,尽管是紧邻兄弟的话也会被这条规则匹配。效果见图1-22. 1111 | 1112 | ~~~html 1113 |
1114 |

Subheadings

1115 |

It is the case that not every heading can be a main heading. Some headings must be subheadings. Examples include:

1116 |
    1117 |
  1. Headings that are less important
  2. 1118 |
  3. Headings that are subsidiary to more important headlines
  4. 1119 |
  5. Headings that like to be dominated
  6. 1120 |
1121 |

Let's restate that for the record:

1122 |
    1123 |
  1. Headings that are less important
  2. 1124 |
  3. Headings that are subsidiary to more important headlines
  4. 1125 |
  5. Headings that like to be dominated
  6. 1126 |
1127 |
1128 | ~~~ 1129 | 1130 | ![图1-22:选择跟随兄弟元素](figure1-22.png) 1131 | 1132 | *图1-22:选择跟随兄弟元素* 1133 | 1134 | 如图所示,两个有序列表都是斜体,因为两个`ol`元素都在`h2`元素后面,且它们(三个)共有一个父元素(`div`)。 1135 | 1136 | ## 伪类选择器 1137 | 1138 | **伪类选择器**非常有趣,它们是一些根据元素状态变化而产生作用的幽灵类。伪类选择器可以根据某些确定元素的状态、文档中的标记模式甚至文档本身的状态选择元素并添加样式。 1139 | 1140 | “幽灵类”的说法可能看起来有点怪,但这个词非常贴切地体现了伪类的工作方式。例如,假如你想要把一个数据表格每隔一行设置为高亮,你可以每隔一行在行元素上加一个`class="even"`,然后写一段CSS把`class`值有`even`的行设置为高亮。但是你也可以使用伪类选择器更简便地实现相同的效果,后面会很快看到它的用法。 1141 | 1142 | ### 组合伪类 1143 | 1144 | 在开始之前,先提一下“链式”。CSS允许(链式)组合伪类选择器,例如,当鼠标停留在(`hover`)一个未访问过的链接(``)上时,将其设置为红色,当鼠标停留在已经访问过的链接上时,将其设置为栗色: 1145 | 1146 | ~~~css 1147 | a:link:hover {color: red;} 1148 | a:visited:hover {color: maroon;} 1149 | ~~~ 1150 | 1151 | (伪类的)顺序无关紧要,`a:hover:link`和`a:link:hover`的效果是一样的。同样的,可以为特定语言的不同状态的链接设置不同的样式,例如德语: 1152 | 1153 | ~~~css 1154 | a:link:hover:lang(de) {color: gray;} 1155 | a:visited:hover:lang(de) {color: silver;} 1156 | ~~~ 1157 | 1158 | 注意不要组合互斥的伪类,例如,一个链接不可能既是访问过的又是没访问过的,所以`a:link:visited`没有任何意义,它并不会匹配任何东西。 1159 | 1160 | ### 结构性伪类 1161 | 1162 | 大部分伪类都是结构性的,既它们是与文档的标记结构相关的。大部分伪类由标签内的结构决定,例如某个伪类选择器选择(某个文档片段中的)第三个段落(`p`)。其他一些选择器允许你处理特定类型的元素。所有的伪类都以一个冒号(`:`)开头,没有例外,而且它们可以出现在选择器的任何位置。 1163 | 1164 | 在开始之前,关于伪类有一点需要明确:伪类永远只指向他们关联的元素,而不是其他元素。这点似乎非常明显而没有必要特意强调,之所以要明确它,是因为在实际使用中,有一些结构型伪类常常被错误地当成后代元素的描述符。 1165 | 1166 | 为了进一步说明这点,我想分享一则我个人的轶事。2003年,我的大女儿,也是我的第一个孩子,出生了。我在网上公布了这个消息(就像你们会做的一样^_^)。许多人回复我表示祝贺,并讲了一些 CSS 的小幽默,许多人用了选择器`#ericmeyer:first-child.`。问题是这个选择器选择的是我,而且只有当我是我父母的第一个孩子的时候才会选择我(巧了,我还真是)。如果要选择我的第一个孩子,选择器应该是`#ericmeyer > :first-child`。 1167 | 1168 | 这种混淆是可以理解的,这就是为何我会在这里提到它,后面的章节我们会经常想起它。只要记住,伪类的作用是给它们绑定的元素添加一些“影子类”,就不容易犯(前面的)错误了。 1169 | 1170 | #### 选择根元素 1171 | 1172 | 这是结构简单性的精髓:伪类选择器`:root`选择文档的根元素。在 HTML 中,根元素**永远是**`html`元素。在为 XML 语言添加样式时,这个选择器会非常有用,因为在不同的语言中根元素可能不同。例如,在 RSS 2.0 中,根元素是`rss`。即使在一种语言(甚至是一个文档)里,也可能会使用不止一个根元素。 1173 | 1174 | 图 1-23 展示了一个给 HTML 中的根元素添加样式的例子: 1175 | 1176 | ~~~css 1177 | :root {border: 10px dotted gray;} 1178 | body {border: 10px solid black;} 1179 | ~~~ 1180 | 1181 | ![图1-23:设置根元素样式](figure1-23.png) 1182 | 1183 | *图1-23:设置根元素样式* 1184 | 1185 | 当然,在HTML文档中,可以直接选择`html`元素,不需要使用`:root`伪类。这两个选择器在特度方面有差异,我们将在第 3 章讨论。 1186 | 1187 | #### 选择空元素 1188 | 1189 | 使用伪类`:empty`,可以选择任何没有子节点的元素——没有任何类型的子元素:**包含**文本节点,包括文字和空白。这有助于筛除 CMS 生成的没有填进任何实际内容的元素。因此,`p:empty {display: none;} `将会让所有空的段落不再显示。 1190 | 1191 | 注意,一个元素如果要被`:empty`匹配,它必须(从解析的角度看)是真正空的——没有空白、可见内容,或后代元素。在下面的元素中,只有第一个和最后一个会被`p:empty`匹配。 1192 | 1193 | ~~~html 1194 |

1195 |

1196 |

1197 |

1198 |

1199 | ~~~ 1200 | 1201 | 第二个和第三个段落不会匹配`:empty`,因为它们不是空的:它们各自包含一个空格和一个换行符,都会被当做文本节点,因此不是空状态。最后一个段落能够匹配,因为注释既不会被当成内容,也不会被当成空白。但是如果在注释的任何一侧添加一个空格或者换行,`p:empty`将不再匹配它。 1202 | 1203 | 你可能会试着为所有空元素设置样式,像这样:`*:empty {display: none;}`,但是这里有个潜在的陷阱:`:empty`会匹配 HTML 的空元素,如`img`和`input`,甚至会匹配`textarea`,除非你为`textarea`元素插入了一些默认文本。因此,从匹配元素的角度来说,`img`和`img:empty`是一样的(它们在特度上有区别,我们将在下一章讨论)。 1204 | 1205 | ~~~html 1206 | North Pacific Salmon 1207 |
1208 | 1209 | 1210 | ~~~ 1211 | 1212 | _**到 2017 年底,`:empty`是唯一一个在匹配元素的时候考虑文本节点的 CSS 选择器。所有 Selectors Level 3 的其他选择器都只考虑元素节点,而完全忽略文本节点——例如,前面讨论过的兄弟组合器**_ 1213 | 1214 | #### 选择唯一子元素 1215 | 1216 | 如果你想过选择所有被链接元素包含的图片,`:only-child`伪类正是为你准备的。它会选择那些是其他元素的唯一子元素的元素。如果你想为所有是其他元素唯一子元素的图片添加边框,可以这样写: 1217 | 1218 | ~~~css 1219 | img:only-child {border: 1px solid black;} 1220 | ~~~ 1221 | 1222 | 这个选择器会匹配所有符合标准的图片,因此,如果有一个段落元素(`p`)包含一个图片并且没有其他子元素,这个图片也会被匹配,而会忽略图片周围的文本。如果你想要选择那些在链接中的的唯一子元素的图片,可以这样设置选择器(效果见图 1-24): 1223 | 1224 | ~~~css 1225 | a[href] img:only-child {border: 2px solid black;} 1226 | ~~~ 1227 | 1228 | ~~~html 1229 |
W3C 1230 | The W3C 1231 | The W3C 1232 | ~~~ 1233 | 1234 | ![图片1-24:选择是链接中的唯一子元素的图片](figure1-24.png) 1235 | 1236 | *图片1-24:选择是链接中的唯一子元素的图片* 1237 | 1238 | 关于`:only-child`需要记住两个地方。第一个是**永远**用伪类选择你想要的唯一的子元素上,而不是它的父元素上,就像前面解释过的一样。这就引入了第二个要记住的地方:当在一个后代选择器中使用`:only-child`时,你并没有严格限定一个父-子关系。 1239 | 1240 | 回到链接-图片的例子,`a[href] img:only-child`匹配的是这样的元素:它们是其它元素的唯一子元素,同时是一个`a`元素的后代元素,而不一定是`a`元素的子元素。匹配的图片元素必须是它直接父元素的唯一子元素,而且是一个`a`元素的后代,它的直接父元素自身可以是一个`a`元素的后代。因此下面的三个图片都会被匹配,如图1-25。 1241 | 1242 | ~~~css 1243 | a[href] img:only-child {border: 5px solid black;} 1244 | ~~~ 1245 | 1246 | ~~~html 1247 | W3C 1248 | W3C 1249 | A link to the web site 1250 | ~~~ 1251 | 1252 | ![图片1-25:选择是链接中的唯一子元素的图片](figure1-25.png) 1253 | 1254 | *图片1-25:选择是链接中的唯一子元素的图片* 1255 | 1256 | 在每种情况下,图片都是它的父元素的唯一子元素,同时是一个`a`元素的后代元素,因此三个图片都会被规则匹配。如果要严格选择那些是一个`a`元素唯一子元素的图片,你只需要简单地添加子元素组合器`a[href] > img:only-child`。这样修改之后,上例中只有第一个图片才会被匹配。 1257 | 1258 | 完美!但是如果在链接元素中存在其他类型的元素的情况下,想选择链接元素中的唯一图片,应该怎么做呢?例如: 1259 | 1260 | ~~~html 1261 | W3C 1262 | ~~~ 1263 | 1264 | 在这种情况下,`a`元素有两个子元素:一个`b`和一个`img`。这个图片不再是它父元素(链接)的唯一子元素,不再会被`:only-child`匹配。但是,它**可以**被`:only-of-type`匹配,如图1-26. 1265 | 1266 | ~~~css 1267 | a[href] img:only-of-type {border: 5px solid black;} 1268 | ~~~ 1269 | 1270 | ~~~html 1271 | W3C 1272 | W3C 1273 | ~~~ 1274 | 1275 | ![图片1-26:选择兄弟元素中的唯一图片](figure1-26.png) 1276 | 1277 | *图片1-26:选择兄弟元素中的唯一图片* 1278 | 1279 | 区别在于:`:only-of-type`会匹配那些在所有兄弟元素中是唯一一个此类型的元素(既所有兄弟元素中没有与其类型相同的元素);而`only-child`会匹配那些根本没有兄弟元素的元素。 1280 | 1281 | 选择段落中的图片,而不用担心段落中链接或其他行内元素的存在: 1282 | 1283 | ~~~css 1284 | p > img:only-of-type {float: right; margin: 20px;} 1285 | ~~~ 1286 | 1287 | 因为在段落的子元素中没有多个图片,因此唯一的图片将会浮动显示。同样可以使用伪类为文档章节中的唯一的`h2`元素添加额外样式: 1288 | 1289 | ~~~css 1290 | section > h2 {margin: 1em 0 0.33em; font-size: 180%; border-bottom: 1px solid gray;} 1291 | section > h2:only-of-type {font-size: 240%;} 1292 | ~~~ 1293 | 1294 | 使用这些规则,任何`section`里面的唯一的`h2`元素将会比通常显示得大一些。如果一个`section`中有两个或更多的`h2`子元素,那么这个`section`中的所有`h2`都不会比此`section`中其他的`h2`显示得大。其他子元素的存在——无论它们是其他级别的标题、段落、表格、列表等等——都不会影响匹配结果。 1295 | 1296 | 有一点要说清楚:`:only-of-type`只涉及元素本身而非其他,看这个例子: 1297 | 1298 | ~~~css 1299 | p.unique:only-of-type {color: red;} 1300 | ~~~ 1301 | 1302 | ~~~html 1303 |
1304 |

This paragraph has a 'unique' class.

1305 |

This paragraph doesn't have a class at all.

1306 |
1307 | ~~~ 1308 | 1309 | 这种情况下,两个段落都不会被选择。为什么呢?因为有两个段落是`div`的后代,他们都不能成为此类型的唯一元素。 1310 | 1311 | 在这里类名是不相关的。我们错在把“类型”当成一个一般描述,这是我们理解语言的方式。**类型**,在`:only-of-type`这里特指元素类型。因此`p.unique:only-of-type`意思是“选择`class`属性中包含`unique`的`p`元素,同时该元素是它和兄弟元素中的唯一一个`p`元素”,而**不是**“选择`class`属性中包含`unique`的`p`元素,同时该元素是它和兄弟元素中的唯一一个`class`属性包含`unique`的`p`元素”。 1312 | 1313 | #### 选择第一个和最后一个子元素 1314 | 1315 | 一个很常见的场景是,给某个元素的第一个或最后一个子元素添加特殊样式。最常见的例子是为一个导航栏的链接添加样式,为第一个或最后一个(或两者都)设置特别的视觉效果。过去需要为元素添加特殊的`class`,现在可以使用伪类来设置。 1316 | 1317 | 伪类`:first-child`用来选择某个元素的第一个子元素,看下面的代码: 1318 | 1319 | ~~~html 1320 |
1321 |

These are the necessary steps:

1322 |
    1323 |
  • Insert key
  • 1324 |
  • Turn key clockwise
  • 1325 |
  • Push accelerator
  • 1326 |
1327 |

Do not push the brake at the same time as the accelerator.

1328 |
1329 | ~~~ 1330 | 1331 | 在这个例子中,是第一个子元素的元素是:第一个`p`、第一个`li`,以及`strong`和`em`元素。使用下面两条规则: 1332 | 1333 | ~~~css 1334 | p:first-child {font-weight: bold;} 1335 | li:first-child {text-transform: uppercase;} 1336 | ~~~ 1337 | 1338 | 会得到如图1-27的结果: 1339 | 1340 | ![图1-27:给第一个子元素添加样式](figure1-27.png) 1341 | 1342 | *图1-27:给第一个子元素添加样式* 1343 | 1344 | 第一条规则把所有是其他元素第一个子元素的`p`设置为粗体,第二条规则把所有是其他元素(在 HTML 中,必须是`ol`或`ul`元素)第一个子元素的`li`设置为大写格式。 1345 | 1346 | 像前面提到的那样,最常见的错误是以为`p:first-child`会选择`p`元素的第一个子元素。记住伪类的本质,是为伪类绑定的元素添加一些影子类,假设把这些影子类真的添加代码里,看起来将会是这样: 1347 | 1348 | ~~~html 1349 |
1350 |

These are the necessary steps:

1351 |
    1352 |
  • Insert key
  • 1353 |
  • Turn key clockwise
  • 1354 |
  • Push accelerator
  • 1355 |
1356 |

Do not push the brake at the same time as the accelerator.

1357 |
1358 | ~~~ 1359 | 1360 | 因此,要选择是其他元素第一个子元素的`em`元素,应该使用`em:first-child`。 1361 | 1362 | 与`first-child`对应的是`:last-child`。使用前面的例子,修改一下样式中的伪类,结果见图 1-28. 1363 | 1364 | ~~~css 1365 | p:last-child {font-weight: bold;} 1366 | li:last-child {text-transform: uppercase;} 1367 | ~~~ 1368 | 1369 | ~~~html 1370 |
1371 |

These are the necessary steps:

1372 |
    1373 |
  • Insert key
  • 1374 |
  • Turn key clockwise
  • 1375 |
  • Push accelerator
  • 1376 |
1377 |

Do not push the brake at the same time as the accelerator.

1378 |
1379 | ~~~ 1380 | 1381 | ![图1-28:给最后一个子元素添加样式](figure1-28.png) 1382 | 1383 | *图1-28:给最后一个子元素添加样式* 1384 | 1385 | 第一条规则把是其他元素最后一个子元素的`p`设为粗体,第二条规则把所有是其他元素子元素的`li`元素设置为大写格式。如果想要选择最后一个段落中的`em`,可以使用`p:last-child em`,它将会选择所有是`p`元素后代的`em`,同时这个`p`是其他元素的最后一个子元素。 1386 | 1387 | 另外,两个伪类可以结合起来成为`:only-child`选择器的另一个版本,下面的两条规则选择相同的元素: 1388 | 1389 | ~~~css 1390 | p:only-child {color: red;} 1391 | p:first-child:last-child {background: red;} 1392 | ~~~ 1393 | 1394 | 设置段落前景色和背景色为红色(不是个好主意)。 1395 | 1396 | #### 选择第一个和最后一个特定类型的元素 1397 | 1398 | 以选择第一个和最后一个子元素的形式,同样可以选择元素中第一个某种类型的子元素。这种方式可以实现选择某个元素中的第一个`table`元素,而不必关心它前面有哪些其他元素。 1399 | 1400 | ~~~css 1401 | table:first-of-type {border-top: 2px solid gray;} 1402 | ~~~ 1403 | 1404 | 这条规则并**不是**作用于整个文档的——并不是选择整个文档的第一个`table`然而忽略其他所有`table`。它只会选择某个子元素里有表格的元素中的第一个`table`元素,而忽略整个元素的子元素中的其他`table`。因此,在图 1-29 的文档结构里,被圈起来的节点是被选中的元素。 1405 | 1406 | ![图1-29:选择第一个表格类型](figure1-29.png) 1407 | *图1-29:选择第一个表格类型* 1408 | 1409 | 在表格中,选择行中的第一个数据单元格而无论当前行中是否有头单元格存在: 1410 | 1411 | ~~~css 1412 | td:first-of-type {border-left: 1px solid red;} 1413 | ~~~ 1414 | 1415 | 这条规则会选择下面每个行中的第一个数据单元格: 1416 | 1417 | ~~~html 1418 | 1419 | Count7611 1420 | 1421 | 1422 | QX- 1423 | 1424 | ~~~ 1425 | 1426 | 相比之下,`td:first-child`会选择第二行中的第一个`td`元素,但不会选择第一行中的元素。 1427 | 1428 | 相对应的是`:last-of-type`,选择兄弟元素中某个类型的最后一个元素。与`:first-of-type`一样,只是它从最后一个元素向第一个元素找。在图 1-30 的文档结构中,被圈起来的节点是选中的元素。 1429 | 1430 | ![图1-30:选择第一个表格类型](figure1-30.png) 1431 | *图1-30:选择第一个表格类型* 1432 | 1433 | 与在`:first-of-type`中提醒的一样,选择元素是在兄弟元素之间,而不是整个文档,亦即每个元素下的子元素集合是分别考虑的,`:last-of-type`分别选择每个子元素集合中的最后一个特定类型的元素。 1434 | 1435 | 与前面说的一样,这两个伪类元素(`:first-of-type`、`:last-of-type`)结合起来成为`:only-of-type`的另一个版本,下面的两个规则选择相同的元素: 1436 | 1437 | ~~~css 1438 | table:only-of-type{color: red;} 1439 | table:first-of-type:last-of-type {background: red;} 1440 | ~~~ 1441 | 1442 | #### 选择每第 n 个子元素 1443 | 1444 | 既然能选择第一个子元素、最后一个子元素、唯一的子元素,如何选择第二个子元素、第三个子元素、第九个子元素?为了避免定义无限多个伪类名称,CSS 使用`:nth-child()`伪类。通过将整数或简单的算术表达式填充到括号中,可以选择任意任意编号的子元素。 1445 | 1446 | 我们先从一个与`:first-child`等价的`:nth-child()`伪类开始,既:`:nth-child(1)`。下面的例子中,被选中的元素的第一个段落和第一个列表项。 1447 | 1448 | ~~~css 1449 | p:nth-child(1) {font-weight: bold;} 1450 | li:nth-child(1) {text-transform: uppercase;} 1451 | ~~~ 1452 | 1453 | ~~~html 1454 |
1455 |

These are the necessary steps:

1456 |
    1457 |
  • Insert key
  • 1458 |
  • Turn key clockwise
  • 1459 |
  • Push accelerator
  • 1460 |
1461 |

Do not push the brake at the same time as the accelerator.

1462 |
1463 | ~~~ 1464 | 1465 | 如果把数字从`1`变成`2`,那么没有段落(`p`)被选中,中间的列表项(`li`)会被选中,如图1-31所示。 1466 | 1467 | ~~~css 1468 | p:nth-child(2) {font-weight: bold;} 1469 | li:nth-child(2) {text-transform: uppercase;} 1470 | ~~~ 1471 | 1472 | ![图1-31:为第二个元素添加样式](figure1-31.png) 1473 | 1474 | *图1-31:为第二个元素添加样式* 1475 | 1476 | 当然,也可以填入任何正数,如果你要选择是某个元素的第 93 个子元素的一个有序列表,可以使用`ol:nth-child(93)`(不是指子元素集合中的第93个有序列表,见下一节)。 1477 | 1478 | 更有用的是,你可以使用简单的算术表达式如`an + b`或`an - b`来定义循环选择,其中`a`和`b`是整数,`n`表示它自己。另外,`+ b`或`- b`的部分如果用不到的话可以去掉。 1479 | 1480 | 假如在一个无序列表中,每三个元素选择第一个,从整个列表的第一项开始,样式可以这样写: 1481 | 1482 | ~~~css 1483 | ul > li:nth-child(3n + 1) {text-transform: uppercase;} 1484 | ~~~ 1485 | 1486 | ![图1-32:为每三个列表项中的第一个设置样式](figure1-32.png) 1487 | 1488 | *图1-32:为每三个列表项中的第一个设置样式* 1489 | 1490 | 这种方式中的`n`可以是0、1、2、3、4、……直到无限大。浏览器会把`3n + 1`处理成1、4、7、10、13、……等等。如果去掉`+ 1`只留下`3n`,结果将是0、3、6、9、12、……等等。因为列表项中没有第0项——所有的元素计数都是从1开始,与数组计数不一样——第一个被这个表达式选中的元素将是列表的第三项。 1491 | 1492 | 元素从1开始计数,因此`:nth-child(2n)`将会选中第偶数个子元素,而`nth-child(2n + 1)`或`nth-child(2n - 1)`会选择第奇数个子元素。你可以记住这两个公式,或者使用另外两个可用于`:nth-child()`的特殊关键字:`even`和`odd`。想从表格的第一行开始每隔一行设置高亮?可以像这样,效果见图 1-33。 1493 | 1494 | ~~~css 1495 | tr:nth-child(odd) {background: silver;} 1496 | ~~~ 1497 | 1498 | ![图1-33:为表格每隔一行设置样式](figure1-33.png) 1499 | 1500 | *图1-33:为表格每隔一行设置样式* 1501 | 1502 | 显然,其他更复杂的选择需要使用表达式`an + b`。 1503 | 1504 | 要注意,当你想使用负数的`b`时,必须把加号去掉,否则整个选择器都将失效。下面的两条规则,只有第一条有效,第二条将会被解析器忽略: 1505 | 1506 | ~~~css 1507 | tr:nth-child(4n - 2) {background: silver;} 1508 | tr:nth-child(3n + −2) {background: red;} 1509 | ~~~ 1510 | 1511 | 如果要选择从第 9 行开始的每一行,可以使用下面两种方式中的任意一个。他们很相似,都选择第 9 行开始的所有行,但后面的方式有更高的特度,将在第 3 章讨论。 1512 | 1513 | ~~~css 1514 | tr:nth-child(n + 9) {background: silver;} 1515 | tr:nth-child(8) ~ tr {background: silver;} 1516 | ~~~ 1517 | 1518 | 如你所愿,有一个对应的伪类`:nth-last-child()`,它与`:nth-child()`效果是一样的,除了是从最后一个元素开始直到第一个元素。如果你想在表格中每隔一行设置高亮,同时需要保证最后一行是高亮的,下面的两条规则可以任选一个: 1519 | 1520 | ~~~css 1521 | tr:nth-last-child(odd) {background: silver;} 1522 | tr:nth-last-child(2n+1) {background: silver;} /* equivalent */ 1523 | ~~~ 1524 | 1525 | 假如 DOM 中的表格添加或移除了行,不需要添加或删除类。结构选择器会一直匹配更新了之后的 DOM 中表格的奇数行。 1526 | 1527 | 只要符合算术规则,每个元素都可以被既被`:nth-child()`又被`:nth-last-child()`选中,下面的规则,效果显示在图 1-34 中: 1528 | 1529 | ~~~css 1530 | li:nth-child(3n + 3) {border-left: 5px solid black;} 1531 | li:nth-last-child(4n - 1) {border-right: 5px solid black;} 1532 | ~~~ 1533 | 1534 | ![图1-34:同时使用 :nth-child 和 :nth-last-child](figure1-34.png) 1535 | 1536 | *图1-34:同时使用 :nth-child 和 :nth-last-child* 1537 | 1538 | 可以把伪类选择器写在一起:`:nth-child(1):nth-last-child(1)`,结合成一个啰嗦版的`:only-child`。除了要创建一个特度更高的选择器,否则没有什么理由这样写,但这确实是一个可选项。 1539 | 1540 | 可以使用 CSS 决定一个当列表中有多少列表项时,相应地为它们设置样式: 1541 | 1542 | ~~~css 1543 | li:only-child {width: 100%;} 1544 | li:nth-child(1):nth-last-child(2), 1545 | li:nth-child(2):nth-last-child(1) {width: 50%;} 1546 | li:nth-child(1):nth-last-child(3), 1547 | li:nth-child(1):nth-last-child(3) ~ li {width: 33.33%;} 1548 | li:nth-child(1):nth-last-child(4), 1549 | li:nth-child(1):nth-last-child(4) ~ li {width: 25%;} 1550 | ~~~ 1551 | 1552 | 例子中,当列表中只有一项时,列表项的宽度是 100%;如果一个列表项既是第一项又是从最后一项开始的第二项,则表示列表总共有 2 个列表项,把它们的宽度设置为 50%;如果一个列表项既是第一个又是从最后一项开始的第三项,则把它和随后的两个兄弟项宽度设置为 33.33%;类似地,如果一个列表项既是第一项又是从最后一项开始的第四项,表示列表总共有四项,把它们宽度设置为 25%; 1553 | 1554 | #### 选择没第 n 个特定类型的子元素 1555 | 1556 | 类似之前的模式,`:nth-child()`和`:nth-last-child()`伪类存在类似的两个选择器:`:nth-of-type()`和`:nth-last-of-type()`。例如,在一个段落中,每隔一个选择链接子元素,从第二个开始选择,可以使用`p > a:nth-of-type(even)`。这个选择器将会忽略所有其他元素(`span`、`strong`等)而只考虑链接元素,见图 1-35: 1557 | 1558 | ~~~css 1559 | p > a:nth-of-type(even) {background: blue; color: white;} 1560 | ~~~ 1561 | 1562 | ![图1-35:选择第偶数个链接](figure1-35.png) 1563 | 1564 | *图1-35:选择第偶数个链接* 1565 | 1566 | 如果想从最后一个链接开始选择,使用`p > a:nth-last-of-type(even)`即可。 1567 | 1568 | 还是像之前说过的一样,这些选择器是在兄弟元素中选择,而不是整个文档。每个元素都有它自己的兄弟元素集合,选择行为发生在每个分组里面。 1569 | 1570 | 还有,你也许想过,两个选择器结合在一起`:nth-of-type(1):nth-last- of-type(1)`会生成一个特度(优先级)更高的`:only-of-type`选择器。(我们真的会在第 3 章解释,我保证。) 1571 | 1572 | ### 动态伪类 1573 | 1574 | 除了结构性伪类之外,还有一些伪类是与(页面标记的)结构相关的,但与前述伪类的不同之处在于:页面的状态会在渲染之后发生变化,而这些伪类会随页面状态的变化而变化。换句话说,样式基于某些文档结构之外的规则来决定是否作用于文档片段,因而无法仅通过文档标记来推断文档片段展示的最终样式。 1575 | 1576 | 听起来好像我们引入了一些随机样式,但实际并非如此。相反,我们是基于某些无法预测的临时条件来应用样式。事实上,样式在何种情况下出现是被明确定义的。这样来想:在某项体育赛事中,每当主队得分,人们就会欢呼。你可能无法预测主队什么时候得分,但一旦主队得分,人群会欢呼这件事却是可以预测的。因此不可以预测的是事件出现的时刻,但可以预测是一旦事件出现时它会导致的行为。 1577 | 1578 | 例如锚点元素(`a`),它(在 HTML 或其它类似文档标准中)定义了从一个文档到另一个文档的链接。锚点一直是锚点,但一些锚点指向的是已经访问过的文档页面,而另一些指向未曾访问过的页面。通过 HTML 标签是无法分辨这种差异的,因为在文档标记中所有的锚点都是一样的。只有通过对比文档中的链接与用户浏览器中的历史记录才能判断两种基本的锚点类型:已访问过的和未曾访问的过的。 1579 | 1580 | ### UI状态伪类 1581 | 1582 | | Name | Description | 1583 | | :------------- | :---------------------------------------------------------------------------------------------- | 1584 | | :enabled | 指启用的用户界面元素(如表单元素);即可供输入。 | 1585 | | :disabled | 指禁用的用户界面元素(如表单元素),即不能输入。 | 1586 | | :checked | 指已被用户或文档本身的默认值选中的单选按钮或复选框。 | 1587 | | :indeterminate | 指既不勾选也不取消勾选的单选按钮或复选框,这种状态只能通过 DOM 脚本来设置,而不是由于用户输入。 | 1588 | | :default | 指默认选择的单选按钮、复选框或选项。 | 1589 | | :valid | 指满足其所有数据有效性语义的用户输入。 | 1590 | | :invalid | 指不符合其所有数据有效性语义的用户输入。 | 1591 | | :in-range | 指用户输入的值介于最小值和最大值之间。 | 1592 | | :out-of-range | 指用户输入的值低于控件允许的最小值或高于最大值。 | 1593 | | :required | 指用户输入必须有一个设定值 | 1594 | | :optional | 指不需要设置值的用户输入。 | 1595 | | :read-write | 指用户可编辑的用户输入。 | 1596 | | :read-only | 指用户不可编辑的用户输入。 | 1597 | 1598 | #### 可用和禁用的 UI 元素 1599 | 1600 | 借助 DOM 脚本 和 HTML5, 可以把用户界面元素(或一组)设置为禁用(disabled)。 1601 | 1602 | 未禁用的元素被定义为可用。 1603 | 1604 | 使用 `:enabled` 和 `:disabled` 伪类选择两个状态。 1605 | 1606 | #### 选中状态 1607 | 1608 | 类型为 “checkbox” 和 “radio” 的 input 元素,Selectors level 3 提供 `:checked`状态伪类,以及`unchecked`。`:interminate`伪类匹配既不是 checked 也不是 unchecked。只有 radio 和 checkbox 可以被 check。其他所有元素和这两个元素的未选中状态都是`:not(:checked)`。 1609 | 1610 | “interminate”状态只能被 DOM 脚本或用户代理设置。可以用来表示用户没有选中或者取消选中某个元素。 1611 | 1612 | #### 默认选项伪类 1613 | 1614 | `:default`伪类。同名 radio 中最初被设置为选中的匹配`:default`,即便用户修改了状态不再匹配 `:checked`时。checkbox 在页面一加载就选中,`:default` 匹配。`select` 元素初始选中的 `option` 匹配 `:default`。 1615 | 1616 | ~~~css 1617 | [type="checkbox"]:default + label { font-style: italic; } 1618 | ~~~ 1619 | 1620 | ~~~html 1621 | 1622 | 1623 | ~~~ 1624 | 1625 | #### 选项伪类 1626 | 1627 | `:required`匹配表单必填项,表示设置了 HTML5 的`required`属性。`:optional`表示没有`required`属性,或者`required`属性有值`false`。 1628 | 1629 | ~~~css 1630 | input:required { border: 1px solid #f00;} 1631 | input:optional { border: 1px solid #ccc;} 1632 | ~~~ 1633 | 1634 | ~~~html 1635 | 1636 | 1637 | 1638 | ~~~ 1639 | 1640 | 第一个元素匹配`:required`,后面两个匹配`:optinal`。 1641 | 1642 | ~~~css 1643 | input[required] { border: 1px solid #f00;} 1644 | input:not([required]) { border: 1px solid #ccc;} 1645 | ~~~ 1646 | 1647 | 不是表单 input 的元素既不是必选项也不是可选项。 1648 | 1649 | #### 合法性伪类 1650 | 1651 | `:valid` `:invalid` 1652 | 1653 | 用于可验证数据合法性的元素,`div`永远不会匹配这两个选择器。 1654 | 1655 | _**这两个伪类由用户代理自己的样式系统决定,可能不会如你预期。例如 2017 年底在多个用户代理中,空的 email input 会匹配 `:valid`,尽快实际上 null 输入不是一个合法的 email 地址。除非验证的使用习惯改进,最好谨慎对待合法性伪类。 **_ 1656 | 1657 | #### 范围伪类 1658 | 1659 | HTML5 的`min`和`max`属性。`:in-range`和`:out-of-range`伪类。 1660 | 1661 | #### 可变性伪类 1662 | 1663 | 可编辑的 input。 1664 | 1665 | `:read-write`、`:read-only` 1666 | 1667 | 例如,在 HTML 中,一个非禁用、非只读的输入元素是 :read-write,任何带有 contenteditable 属性的元素也是如此。其他所有元素都是 :read-only 1668 | 1669 | ### `:target`伪类 1670 | 1671 | URL 中包含一个片段标识码,在 CSS 中叫做 *target*,可使用`:target`伪类为其添加样式。 1672 | 1673 | ~~~ 1674 | http://www.w3.org/TR/css3-selectors/#target-pseudo 1675 | ~~~ 1676 | 1677 | 多亏了 :target,你可以在文档中突出显示任何目标元素,或者你可以为不同类型的目标元素设计不同的风格--例如,为目标标题设计一种风格,为目标表格设计另一种风格,等等。 1678 | 1679 | :target 样式在两种情况下不会被应用。 1680 | 1681 | 如果页面是通过一个没有片段标识符的URL访问的。 1682 | 1683 | 如果通过具有片段标识符的URL访问页面,但该标识符不匹配文档中的任何元素。 1684 | 1685 | ### `:lang`伪类 1686 | 1687 | ### 否定伪类 1688 | 1689 | Selector level 3 `:not()` 1690 | 1691 | 括号中填写**简单选择器**,简单选择器在 W3C 的定义:类型选择器、通配选择器、属性选择器、类选择器、ID选择器或伪类中的一个。简单选择器是不包含祖先-后代关系的选择器。 1692 | 1693 | ## 伪元素选择器 1694 | 1695 | CSS2 定义了四个基本的微元素选择器,元素的第一个字母,元素的第一行,before 和 after。 1696 | 1697 | ### 样式化第一个字母 1698 | 1699 | ~~~css 1700 | p::first-letter {color: red;} 1701 | ~~~ 1702 | 1703 | ### 样式化第一行 1704 | 1705 | ~~~css 1706 | p::first-letter {color: red;} 1707 | ~~~ 1708 | 1709 | ### `::first-letter`和`::first-line`的限制 1710 | 1711 | 只能用于块级元素,不能用于行内元素。允许使用的属性: 1712 | 1713 | |::first-letter| ::first-line| 1714 | |-----|-----| 1715 | |All font properties|All font properties 1716 | |All background properties|All background properties 1717 | |All text decoration properties|All margin properties 1718 | |All inline typesetting properties|All padding properties 1719 | |All inline layout properties|All border properties 1720 | |All border properties|All text decoration properties 1721 | |box-shadow|All inline typesetting properties 1722 | |color|color 1723 | |opacity|opacity 1724 | 1725 | ### 在元素之前或之后样式化(或创建)内容 1726 | 1727 | ~~~css 1728 | h2::before {content: "]]"; color: silver;} 1729 | ~~~ 1730 | 1731 | ~~~css 1732 | body::after {content: "The End.";} 1733 | ~~~ 1734 | 1735 | ## 总结 1736 | 1737 | 通过使用基于文档语言的选择器,作者可以创建适用于大量类似元素的CSS规则,就像他们可以构建适用于非常狭窄环境的规则一样容易。将选择符和规则组合在一起的能力使样式表保持紧凑和灵活,这顺便带来了更小的文件大小和更快的下载时间。 1738 | 1739 | 选择符是用户代理通常必须正确处理的一件事,因为无法正确解释选择符几乎会阻止用户代理使用CSS。反过来说,对于作者来说,正确编写选择符是至关重要的,因为错误会阻止用户代理按照预期的方式应用样式。正确理解选择符以及如何将它们组合起来的一个不可或缺的部分,是对选择符与文档结构的关系,以及在决定元素如何被设计成风格时,继承和级联等机制如何发挥作用的深刻理解。 1740 | -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-1.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-10.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-11.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-12.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-13.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-14.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-15.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-16.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-17.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-18.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-19.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-2.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-20.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-21.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-22.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-23.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-24.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-25.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-26.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-27.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-28.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-29.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-3.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-30.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-31.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-32.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-33.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-34.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-35.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-4.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-5.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-6.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-7.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-8.png -------------------------------------------------------------------------------- /docs/2_Selectors/figure1-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/2_Selectors/figure1-9.png -------------------------------------------------------------------------------- /docs/3_Specificity_and_the_Cascade/README.md: -------------------------------------------------------------------------------- 1 | # 特度和层叠 2 | 3 | _**继承**_机制指元素的属性值被传递给它的后代。用户代理通过继承和_**特度**_决定应用哪些(样式)值被应用于元素,这个处理过程叫做_**层叠*_. 4 | 5 | 本章三个机制:特度、继承和层叠。 6 | 7 | ## 特度 8 | 9 | ### 声明和特度 10 | ### 全局选择器特度 11 | ### ID和属性选择器特度 12 | ### 行内样式特度 13 | ### 重要性 14 | 15 | ## 继承 16 | 17 | ## 层叠 18 | 19 | ### 按重要性和来源排序 20 | ### 按特度排序 21 | ### 按顺序排序 22 | ### 非CSS显示标识 23 | 24 | ## 总结 25 | 26 | ### 特度注意点 27 | - 特度优先级值 x,y,z,w 分别对应于 28 | - x:行内样式 29 | - y:ID 选择器 30 | - z:类、属性、伪类选择器 31 | - w:标签、伪元素选择器 32 | - 添加了 `!important` 标记的属性需单独考虑 33 | -html 元素没有设置 background 属性但 body 元素设置了 background 时,body 的 background 属性会传递给 html 元素,继承机制的唯一例外 34 | - 尽量不要使用全局通配符 `*`,会破坏继承(被破坏的元素属性可使用值 `inherit` 修复) 35 | - 标签状态添加样式的建议顺序:link-visited-focus-hover-active LVFHA 36 | 37 | ### 元素应用样式的规则 38 | 1. 找出所有选择器可以匹配此元素的规则 39 | 2. 按照 explicit weight 排序所有声明,所有标记为 !important 的规则拥有更高的权重 40 | 3. 按照样式来源排序所有声明,三个 origin:author、reader 和 user angent;绝大部分环境中 reader !important > author !important > author > reader > user agent 41 | 4. 按照特度排序所有声明 42 | 5. 按照样式表或文档中的位置排序所有声明,在后面的规则拥有更高权重。Import 的样式表插入在当前样式表的最前面 43 | -------------------------------------------------------------------------------- /docs/4_Values_and_Units/README.md: -------------------------------------------------------------------------------- 1 | # 值和单位 2 | 3 | ## 关键字、字符串和其他文本值 4 | 1. CSS3 三个 global keywords:inherit、initial、unset 5 | 1. inherit 也可设置默认不继承的属性 6 | 2. initial 设置为默认值,属性没有默认值时设置为用户代理设置的值 7 | 3. unset 当属性可继承时行为与 inherit 相同,非继承属性时行为与 initial 相同 8 | 4. IE 11 不支持它们,也不支持 all 9 | 5. 属性 all 的值只能使用 global keywords 10 | 2. 字符串值,使用单引号或双引号包起来的直接引用的值,可用 \ 在行末断行,真的要插入换行符使用 \A 11 | 3. url值使用相对地址时,相对的是样式文件的位置,url和左括号之间不能插入空格 12 | 4. images:一般是 url 值,或者 image-set(),或者 gradients 渐变图片 13 | 5. 有些属性接受标识符值,用户自定义的 identifier 14 | 15 | ## 数值和百分比 16 | 1. 整数值 +- 符号,一些属性超出取值范围的时候,取距离最近的值,z-index 没有严格范围 ±1,073,741,824 (±230) 17 | 2. 数值,包含整数值和浮点值,超出范围时一些属性会失效,一些会同整数值行为 18 | 3. 百分比一般是相对于其他值的值,任何接受百分比值的属性将定义对允许的百分比值范围的任何限制,还将定义相对计算百分比的方式。 19 | 4. 分数值,标签 fr,用于 Grid Layout 20 | 21 | ## 距离 22 | 度量长度,长度都由正/负的数值加上标签(缩写的长度单位),0 不需要跟随单位 23 | 24 | 1. 绝对长度单位 25 | 1. in、cm、mm、q(1cm = 40q)、pt(1in = 72pt)、pc(1pc = 12pt)、px(1/96 in defined in css) 26 | 2. CSS 2.1 / 3 建议 96 ppi,多数显示器高于此数值,打印设备假定 96px 为1inch 27 | 2. 分辨率单位,用于 Media query 和 响应式设计 28 | 1. dpi 每英寸点数,打印纸点、LED 屋里像素、电子墨水显示器 Kindle 29 | 2. dpcm 同上,每厘米点数 30 | 3. dppx 每个 CSS px 单位的点数,CSS3 约定比率 1dppx 等于 96dpi 31 | 3. 相对长度单位 32 | 1. em,相对于本元素 font-size 的值,当设置 font-size 属性时,em 是相对于父元素的 font-size;名称来源于小写字母 m 的宽度, 但 CSS 中并不精确等于 33 | 2. ex,小写字母 x 的高度,不同字体有不同的 x 高度 34 | 3. rem,基于根元素 font-size 值,基于绝对 px 而非相对字体大小 ,html {font-size: 75%;} 得到值12px 而非 75%(假设默认 font-size 是 16px);支持 initial 关键字的浏览器中,如果根元素没有设置字体大小,font-size: 1rem 等于 font-size: initial 35 | 4. Viewport 相对单位, CSS3 中新增,依据视口尺寸百分之一 36 | 1. vw、vh、vmin、vmax(视口宽高中较小或较大的一个) 37 | 38 | ## 计算值 39 | 1. calc() 可进行简单四则运算,可以使用括号 40 | 2. 可使用在这些值类型允许使用的地方:长度、频率、角度、时间、百分比、数值、整数 41 | 3. `+ -` 号两边必须使用同样的值类型,`*` 号一边必须是数值,/ 号右侧必须是数值,不能 0 除 42 | 4. `+ -` 号两边必须有空格, * / 非必须 43 | 5. 规范要求用户代理必须支持最少 20 terms 44 | 45 | ## 属性值 46 | 1. `attr()` 少数 CSS 属性允许使用当前元素 HTML 属性的值:`p::before {content: "[" attr(id) "]";}` 47 | 2. `input[type="text"] {width: attr(maxlength em);}` 48 | 3. 2016 年底还都不支持 49 | 50 | ## 颜色 51 | 1. 命名颜色, 16 to 148 in CSS Color Module Level 4 base on X11 RGB 52 | 2. RGB 和 RGBa 颜色 53 | 1. `rgb(R, G, B)` 取值 0 - 255、0% - 100%,超出范围取上下限,浮点数值四舍五入为 0 - 255 整数 54 | 2. `Rgba(R, G, B, a)`,a 取值 0 - 1,超出范围无效或重置为上下限,不能使用百分比 55 | 3. 十六进制 RGB 56 | 4. 十六进制 RGBa,2017 年底 Firefox 和 Safari 支持, Chrome 和 Opera 试验性实现 57 | 3. HSL 和 HSLa 颜色:CSS3 新增, H 色调 0 - 360、 S 饱和 0 - 100%、 L 亮度 0 - 100% 58 | 4. 颜色关键字,可使用在任何允许使用颜色值的地方 59 | 1. `transparent` 完全透明颜色,背景颜色默认值,常用于定义渐变 60 | 2. `currentColor` 当前元素 color 属性的值 61 | 62 | ## 角度 63 | 1. 数值 + 单位:deg 360角度、grad 400一圈、rad 弧度 2π、turn 一圈 64 | 65 | ## 时间和频率 66 | 1. 数值 + s/ms 67 | 2. 数值 + Hz/kHz 忽略大小写 68 | 69 | ## 位置 70 | 1. 取值顺序 71 | ~~~ 72 | [ 73 | [ left | center | right | top | bottom | | ] | 74 | [ left | center | right | | ] 75 | [ top | center | bottom | | ] | 76 | [ center | [ left | right ] [ | ]? ] && 77 | [ center | [ top | bottom ] [ | ]? ] 78 | ] 79 | ~~~ 80 | 2. 如果只声明一个值,第二个值默认设置为 `center` 81 | 3. 如果声明两个值且第一个值为长度或百分比,则第一个值 always 被当做水平值 82 | 4. 如果声明四个值,必须有两个值是长度或百分比,每个值前面有一个关键字,`right 10px bottom 30px` 表示从右边向左 10px 和 从底边向上 30px 83 | 5. 如果定义三个值,与四个值一样,最后一个值默认为 0 84 | 85 | ## 自定义值 86 | 1. 以 -- 开始, 区分大小写 87 | 2. 可以 scope 覆盖 88 | 3. 记得使用 @supports() 验证哦 89 | 4. 浏览器支持尚不确定 90 | ~~~css 91 | @supports (color: var(--custom)) { 92 | /* variable-dependent styles go here */ 93 | } 94 | @supports (--custom: value) { 95 | /* alternate query pattern */ 96 | } 97 | html { 98 | --gutter: 3ch; 99 | --offset: 1; 100 | } 101 | ~~~ 102 | -------------------------------------------------------------------------------- /docs/5_Fonts/README.md: -------------------------------------------------------------------------------- 1 | # 字体 2 | 3 | 字体无法绝对控制,使用的字体下载失败,fallback 到用户浏览器的字体。 4 | 5 | ## Font Families 6 | 1. CSS 定义的五种字体: 7 | 1. Serif fonts:有衬线、不等宽, Times,Georgia,New Century Schoolbook 8 | 2. Sans-serif fonts:成比例、无衬线,Helvetica,Geneva,Verdana,Univers 9 | 3. Monospace fonnts:不成比例,字符等宽,有或者无衬线,Courier, Courier New, Consolas, and Andale Mono 10 | 4. Cursive fonts:模拟手写,花体/草体?Zapf Chancery,Author,Comic Sans 11 | 5. Fantasy fonts:其他类型,不能归为上面的,装饰、显示字体,Western,Woodblock,Klingon 12 | 2. 字体名中间有空格、尾部有# $等符号,建议使用引号, 字体中有关键字(cursive 等) 13 | ~~~css 14 | p {font-family: Times, 'Times New Roman', 'New Century Schoolbook', Georgia,'New York', 'Karrank%', serif;} 15 | ~~~ 16 | 17 | ## @font-face 18 | ~~~css 19 | @font-face { 20 | font-family: "SwitzeraADF"; 21 | src: local("Switzera-Regular"), 22 | local("SwitzeraADF-Regular "), 23 | url("SwitzeraADF-Regular.otf") format("opentype"), 24 | url("SwitzeraADF-Regular.true") format("truetype"); 25 | } 26 | ~~~ 27 | 1. 懒加载,浏览器实现若不是这样的需要被当做bug 28 | 2. 字体需要与样式同源,除非服务器设置 Access-Control-Allow-Origin. 29 | 3. 其中的font-family是描述符descriptor不是属性,描述符定义字体名之后,插入到用户代理的字体表中;样式中字体属性的值使用该名称可以refer到该字体 30 | 4. format(),用户代理可跳过下载不支持的格式:embedded-opentype EOT,opentype OTF,svg SVG,truetype TTF,woff WOFF 31 | 5. Flash of Unstyled Content Flash of Un-Fonted Text,浏览器加载所有资源前显示内容,字体变化可能引起重排,(e.g.字体高度差别较大) 32 | 6. local() 检查本地字体先,local可用来重命名本地字体 33 | 7. 34 | ~~~css 35 | @font-face { 36 | font-family: "SwitzeraADF"; 37 | src: url("SwitzeraADF-Regular.eot"); 38 | src: url("SwitzeraADF-Regular.eot?#iefix") format("embedded-opentype"), 39 | url("SwitzeraADF-Regular.woff") format("woff"), 40 | url("SwitzeraADF-Regular.ttf") format("truetype"), 41 | url("SwitzeraADF-Regular.svg#switzera_adf_regular") format("svg"); 42 | } 43 | ~~~ 44 | - 前两行fix IE6 - IE9, 45 | - woff: web open font format 大部分现代浏览器, 46 | - ttf: 大部分 iOS和Androids设备, 47 | - svg: 旧iOS 48 | 49 | ## font-weight 50 | 1. 100 - 900 keywords normal bold lighter bolder;基准:400 = normal,700 = bold 51 | 2. 字体本身定义的weight,就近匹配,只保证数值大的显示的weight大于等于数值小的 52 | 3. 假如只定400为基准,normal、regular等 等于 400同时Medium 等于 500,但如果只有Medium,则等于400 53 | 4. 接上条,如果500没有对应的变体,与400相同; 54 | 5. 接上条,如果没有300对应的变体,300对应到比400小一级的变体,如果也没有,与400相同;同样的方法用与200和100; 55 | 6. 接上条,如果没有600对应的变体,600对应到比500darker一级的变体,如果也没有,与500相同;同样的方法用于700,800和900; 56 | 7. 值 bolder 和 lighter,相对父级继承的weight基础上加重或减轻,若存在比父级更重/轻一级的变体,则应用该级变体;如果没有,则在父级weight数值基础上加/减100,直到900/100 57 | 8. @font-face中的font-weight可按数值指定 58 | 59 | ## font-size 60 | 1. 值larger和smaller类似font-weight的bolder和lighter 61 | 2. 约定一个 em 大小的方块,但是字符未必完全显示在方块内部,由字体本身的设计决定;baseline之间的默认距离,大部分字体的字符定义低于这个距离 62 | 3. 绝对尺寸:xx-small, x-small, small, medium, large, x-large, and xx-large 63 | 1. css1约定1.5倍步进or 0.66 64 | 2. css2约定1.0 - 1.2 之间 65 | 3. css3草案重新约定各个值 66 | 4. 相对尺寸:larger和smaller 67 | 5. 百分比和em一样 68 | 6. font-size继承是继承父级的计算值(百分比累加) 69 | 7. 渲染引擎差异 OOOOOOOOOO 10px - 10.5px- 11px,不同OS上不同浏览器的不同表现 70 | 8. 71 | ~~~css 72 | p {font-size: medium;} /* the default value */ 73 | span {font-family: monospace; font-size: 1em;} 74 | ~~~ 75 | 默认medium大小为16px,设置在span上的monospace,span继承 medium,某些浏览器计算font-size的时候,参照用户performance settinng来设定实际的文字大小,一般默认是13px;使用: 76 | ~~~css 77 | p {font-size: medium;} /* the default value */ 78 | span {font-family: monospace, serif; font-size: 1em;} 79 | ~~~ 80 | 添加一个额外的serif,所有浏览器会使用medium的计算值继承给span,而不使用medium的原始值。 81 | 9. font-size可以使用长度单位,使用 pixel-sizing text 获得一致性,但确定是不总是能resize to pixel,移动设备。。。所以不推荐? 82 | 10. 自动调整尺寸 83 | 1. 字体清晰度取决于size和x-height which referred to aspect value,as 有较大aspect value的字体随着尺寸缩小比值小的字体更清晰 84 | 2. font-size-adjust属性:Declared font-size × (font-size-adjust value ÷ aspect value of available font) = Adjusted font-size 85 | 3. 不同字体的 x-height 不同导致声明相同的font-size的时候,实际显示的 adjusted font-size不同,使用 font-size-adjust 设定参数,调整字体实际显示的adjusted font-size 86 | 4. 字体的 aspect value,支持@font-face的浏览器可以直接从字体文件中取,字体文件里可能没有,用户代理会试着计算,no guarantee 87 | 5. 使用值auto,使用浏览器计算的aspect值,none是默认值 88 | 6. 2017年底只有Gecko支持 89 | 90 | ## font-style 91 | 1. normal italic oblique 92 | 93 | ## font-stretch 94 | 1. 字体压缩or舒展,若@font-face约定了值,可以设定,否则无效 95 | 2. 2017年底,mac和ios的safari不支持 96 | 97 | ## font-kerning 98 | 1. 字符间距的方式 AB and AW may have different separation distances 99 | 2. If a font does not contain kerning data, font-kerning will have no effect. 100 | 3. 属性letter-spacing可用于kerned字体,kerning之后由letter-spacing设定间距 101 | 102 | ## font-variant 103 | ## font-feature-settings 104 | ## font-synthesis 105 | 106 | ## font属性 107 | 1. `[[ ‖ [ normal | small-caps ] ‖ ]? [ / ]? ] | caption | icon | menu | message-box | small-caption | status-bar` 108 | 2. font属性值的覆盖,整个是一个属性,值会一起背新值覆盖 109 | 3. 使用系统字体:`caption | icon | menu | message-box | small-caption | status-bar` 110 | 111 | ## 字体匹配 112 | 1. 用户代理创建字体数据库,列出CSS属性里的所有字体;机器上的所有字体,用户自定义字体 113 | 2. 分离元素为每个元素构建一个显示内容时必需的字体列表,基于列表选择一个显示元素的初始字体族;若完全匹配,使用该字体,否则; 114 | 3. 首先匹配 `font-stretch` 属性 115 | 4. 再匹配 `font-style`,The keyword italic is matched by any font that is labeled as either “italic” or “oblique.” If neither is available, then the match fails 116 | 5. 然后匹配 `font-weight` 117 | 6. 匹配 `font-size`,范围匹配 118 | 7. 若第二步没有匹配,找同字体族中的可选字体,若有重复步骤2 119 | 8. 如果一个普通匹配被找到,但没有显示元素需要的所有东西 then the user agent goes back to Step 3, which entails a search for another alternate font and another trip through Step 2. 120 | 9. Finally, if no match has been made and all alternate fonts have been tried, then the user agent selects the default font for the given generic font family and does the best it can to display the element correctly. 121 | -------------------------------------------------------------------------------- /docs/6_Text/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/6_Text/1.png -------------------------------------------------------------------------------- /docs/6_Text/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/6_Text/2.png -------------------------------------------------------------------------------- /docs/6_Text/README.md: -------------------------------------------------------------------------------- 1 | # 文本属性 2 | 3 | 文本是内容,字体是用来显示内容的 4 | 5 | ## 缩进和行内对齐 6 | 1. block 方向和 inline 方向,大部分语言从上至下,从左至右 7 | 2. `text-indent` 用于块级元素,缩进发生于 inline 方向,值为`长度|百分比`,只缩进第一行 8 | 3. If you want to “indent” the first line of an inline element, you can create the effect with left padding or margin. 9 | 4. 使用百分比值时,相对于包含块(父元素)的宽度 10 | 5. `text-align`: `start | end | left | right | center | justify | match-parent | start end` 11 | 6. 用于块元素,CSS Text Module Level 3 默认为 `start` 12 | 7. `text-align-last`: `auto | start | end | left | right | center | justify`,用于块级元素的每个换行位置的前一行的对齐(浏览器支持) 13 | 14 | ## 行内对齐 15 | ![](1.png) 16 | 1. `line-height` 设定文本 baseline 之间的间距,` | | | normal`,百分比值时相对 font-size 17 | 2. leading,line-height 和 font-size 的差值 18 | 3. 用于块级元素时,定义的是元素文本 baseline 的最小间距 19 | 4. `line-height` 减去 `font-size` 的值等分两半放在 content area 上下,可为负值 20 | 5. A line box is exactly as tall as needed to enclose the top of the tallest inline box and the bottom of the lowest inline box. 21 | 6. `line-height` 默认 `normal`,用户代理设置,一般约为 font-size 的1.2倍;line-height 继承具体的值或比率 (补:严重依赖 font-families 自身设置) 22 | 7. `vertical-align` 用于行内元素和 image、input 等替换元素、table-cells等,不继承,使用百分比值时相对于 `line-height` 23 | 8. Remember: `vertical-align` **does not** affect the alignment of content within a **block-level** element. You can, however, use it to affect the vertical alignment of elements within table cells. 24 | 9. `vertical-align: baseline` 强制元素的 baseline 和父元素的 baseline 对齐,图片、input 等没有 baseline 的将底部对齐父元素 baseline,even if there is no other text in the line. 25 | 10. `vertical-align`: `sub`、`super`,baseline 低于或高于父元素 baseline,具体数值由用户代理决定,此值不改变 font-size 26 | 11. `vertical-align: bottom` 把元素的 inline box 的底部与 line box 的底部对齐 27 | 12. `vertical-align: text-bottom` 元素的 inline box 的底部与默认 text box 的底部对齐,默认 text box 由父元素的 font-size 确定 28 | 13. `vertical-align`: `top` `text-top` 与 `bottom` `text-bottom` 相反 29 | 14. `vertical-align: middle` 元素的垂直中线与父元素 baseline 向上 1/4 em(1/2 ex)处对齐,常用于图片,baseline 向上的距离由用于代理决定,理论上可能有所不同 30 | 15. `vertival-align` 百分比值,元素 baseline 相对父元素 baseline 提升或降低(负值),百分比是相对于当前元素(非父元素)的 line-height 31 | 16. `vertival-align` 长度数值,基于本位置提升或降低指定的长度值 32 | 17. 设置 `vertival-align`,使得元素有自己的 inline box,会影响 line box 的高度 33 | 34 | ## Word Spacing and Letter Spacing 35 | 1. `word-spacing` 并不总是能识别不同语言中的“word” 36 | 2. `word-spacing` 和 `letter-spacing` 会继承,但无法像 `line-height` 那样设置一个相对值 37 | 38 | 39 | ## Text Transformation 40 | 1. `uppercase | lowercase | capitalize | none`,`capitalize` 视用户代理实现为`'Heading-one'` 或 `'Heading-One'` 41 | 42 | ## Text Decoration 43 | 1. `none | [ underline ‖ overline ‖ line-through ‖ blink ]` 44 | 2. 可联合使用: `h2 {text-decoration: underline overline;}` 45 | 3. 元素非继承,但子元素无法使用 `none` 清除父元素的 `underline` 等,决定于用户代理 46 | 47 | ## Text Rendering 48 | 49 | ## Text Shadows 50 | 1. `none | [ ?]#` 51 | 2. 两个 length,表示水平和垂直 offset,第三个可省略,模糊半径:从阴影外边缘到模糊范围边缘,具体的模糊方法由用户代理决定 52 | 3. 特大范围阴影可能造成性能问题 53 | 54 | ## 处理空格 55 | 1. `white-space` 设置浏览器对待 word 和 line 之间的空格的方式,CSS2.1 之前用于块级元素,之后用于所有元素 56 | 2. XHTML 多个空格合成一个,忽略元素中的换行 57 | 3. `white-space: normal;` 删除多余空格,换行转换成空格,同一行的多个空格变成一个 58 | 4. `white-space: pre;` 像 XHTML中的 `
`,不忽略空格
 59 | 5. `white-space: nowrap;` 防止wrap,只有使用 `
` 才能换行,参照 HTML4 的 `` 60 | 6. `tab-size: | ` tab 占几个空格,用于块级元素,继承 61 | 7. `white-space`设置了合并空格,`tab-size`会被忽略,还会被计算但不可见 62 | 8. 目前 WebKit and Gecko (as –moz-tab-size) 只支持 `Integer` 63 | 64 | | value | Whitespace | Line feeds | Auto line wrapping | 65 | ----|----|----|---- 66 | pre-line | Collapsed | Honored | Allowed 67 | normal | Collapsed | Ignored | Allowed 68 | nowrap | Collapsed | Ignored | Prevented 69 | pre | Preserved | Honored | Prevented 70 | pre-wrap | Preserved | Honored | Allowed 71 | 72 | ## Wrapping and Hyphenation (包裹和断字) 73 | ![](2.png) 74 | 1. `hyphens` 决定 word 在何处 break,高度依赖具体语言 75 | 2. `word-break`: `normal | break-all | keep-all` 76 | 3. soft wrap 指文字太长,由用户代理或 OS 决定换行,`word-break` 可修改行为(换行符、`
` 为 hard wrap) 77 | 4. `break-all` 时不显示 hyphens(`line-break`属性会影响行为) 78 | 5. `keep-all` 去除所有单词中的 soft wrap,行为类似 `white-space: pre;` 79 | 6. `line-break`,As we just saw, `word-break` can affect how lines of text are soft wrapped in CJK text. The `line-break` property also affects such soft wrapping, specifically how wrapping is handled around CJK-specific symbols and around non-CJK punctuation (such as exclamation points, hyphens, and ellipses) that appears in text declared to be CJK. 80 | 7. `overflow-wrap / word-wrap`: `normal` `break-word` 81 | 8. `break-word` 和 `word-break: break-all` 的区别: `word-wrap: break-word` 当有可能使用空白断行时会使用而不会断词, `word-break: break-all `不管这些,会直接断单词 82 | 83 | ## Writing Modes 84 | 1. `writing-mode`: `horizontal-tb | vertical-rl | vertical-lr`,一些细节:block 方向和 inline 方向 85 | 2. `text-orientation` 字体方向 86 | 3. direction: `ltr | rtl` 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/7_Basic_Visual_Format/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/7_Basic_Visual_Format/1.png -------------------------------------------------------------------------------- /docs/7_Basic_Visual_Format/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/7_Basic_Visual_Format/2.png -------------------------------------------------------------------------------- /docs/7_Basic_Visual_Format/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/7_Basic_Visual_Format/3.png -------------------------------------------------------------------------------- /docs/7_Basic_Visual_Format/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/7_Basic_Visual_Format/4.png -------------------------------------------------------------------------------- /docs/7_Basic_Visual_Format/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN/a229db194f2ca0d3ab96c19d478b7f82544db307/docs/7_Basic_Visual_Format/5.png -------------------------------------------------------------------------------- /docs/7_Basic_Visual_Format/README.md: -------------------------------------------------------------------------------- 1 | # 基本视觉格式化 2 | 3 | ## 基本盒模型 4 | ![](1.png) 5 | 1. 所有元素都生成一个或多个矩形盒 element boxes 6 | 2. `background` 默认在 `padding-area` 7 | 3. border color 默认取前景色 text color 8 | 4. 普通流,从左向右、从上向下,非西语流的方向可能会不同 9 | 5. `inline-block` box 表现类似替换元素 10 | 6. containing block,每个元素盒有个包含块,layout context,通常是父元素盒 11 | 7. html 元素是 initial containing block,It's unique in that the viewport— 12 | the browser window in screen media, or the printable area of the page in print media—determines its dimensions, not the size of the content of the root element. 13 | 14 | ## 改变元素显示 15 | ![](2.png) 16 | ![](3.png) 17 | 1. `display`: `block` `inline` 等修改的是元素的 display role,而非把元素变成块级或行内元素 18 | 2. `box-sizing` 属性可用于所有接受宽度或高度值的元素 19 | 3. 七个属性值(`margin-left border-left padding-left width padding-right border-right margin-right`)相加等于包含块的宽度,通常(都是块级时,不设置 `box-sizing`)是父元素的`width`,只有 `width` 和 `margin` 可以设置为 `auto`,其他属性需要设置为特定值或 `0`,只有 `margin` 可为负值 20 | 4. 违反上条时,将把 `margin-right` 强制设置为 `auto`, overconstrained 21 | 5. 使用百分比单位时,相对于包含块的宽度,`border` 无法使用百分比单位 22 | 6. 块级替换元素规则与上述规则相同(img) 23 | 7. 垂直方向七个属性值(类似宽度)相加等于包含块的高度,与宽度不同的是: 24 | 8. 普通流中,如果 `margin-top` 或 `margin-bottom` 设置为 `auto`,将会自动设置为 `0` 25 | 9. 使用百分比高度时,`height` 相对于包含块高度,但当包含块高度为 `auto` 时,`height` 被重置为 `auto` 26 | 10. 百分比的 `margin-top` `margin-bottom` `padding-top` `padding-bottom` 都相对于包含块**宽度** 27 | 11. 普通流块盒使用 `height: auto` 时,正好高到包含它所有的 inline 内容的 line boxes;有唯一块级子元素时,默认高度从子元素 outer border 顶部到 bottom border 底部,不包含 margin;但当块有 top 或 bottom padding 或border时 ,高度将从outer-top margin 顶部到 outer-bottom margin 底部 28 | 12. 垂直方向的 margin 折叠,存在负值时,与正值相加 29 | 13. `list-item` 的 marker 不是 list item 的 content-area 的一部分 30 | 31 | ## 行内元素 32 | 33 | 1. 行内元素的 content area,每个字符的 em boxes 拼在一起;替换元素的是元素自然高度加上margins borders 或 padding [参考](https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align 34 | ) 35 | 2. Inline box 是 content area 加上下两个 half-leading,高度等于 `line-height`;替换元素的 inline box 高度等于 content area,因为没有 leading 36 | 3. line box 把该行最高和最低 inline boxes 包裹起来的最矮的box,参见第六章文本属性 37 | 4. content area 类似于块盒的 content box 38 | 5. inline 元素的背景应用于 content area 加上 padding (padding-area) 39 | 6. Any border on an inline element surrounds the content area plus any padding and border. 40 | 7. padding borders margins 在非替换元素上不会对 inline 元素或它的盒产生垂直效果,不影响元素行内盒的高度(以及 line box 的高度) 41 | 8. 替换元素的 margins 和 borders 影响行内盒高度,和 line box 高度 42 | 9. 决定行内的每个元素的行内盒高度的步骤: 43 | 1. 找出不是 inline 元素后代的 inline 非替换元素和文本的 font-size 和 line-height 值,combine them;line-height 减去 font-size 算出 leading 44 | 2. 找出每个替换元素的 height,margin,border,padding 的值加在一起 45 | 3. 对每个 content area,找出它高出整行的 baseline 多少以及低于 baseline 多少;这需要知道每个元素、匿名文本和行本身的 baseline,line them all up;替换元素的底边在整行 baseline 上 46 | 4. 根据元素的 vertical-align 值决定垂直偏移量,元素的inline box会移动多远,修改它高于或低于baseline多少 47 | 5. 计算最终的 line box height,highest inline box top 与 baseline的距离 + lowest inline box bottom 与 baseline 的距离 48 | 10. 行高是由组成它的元素和文本等其他内容决定的,`line-height` 属性只影响行内元素和其他行内内容,而非块级元素;只有当块级元素内包含行内内容的时候,`line-height` 会作用于行内内容 49 | 11. 12px 24px 文本, line-height 设置为12px,文本默认 all baseline-aligned 50 | ![](4.png) 51 | 12. `vertical-align` 属性值:结合上一章 52 | 1. `top`,元素 inline box top 与 containing line box top 对齐 53 | 2. `bottom`,元素 inline box bottom 与 containing line box bottom 对齐 54 | 3. `text-top`,元素 inline box top 与 parent 的 content area top 对齐 55 | 4. `text-bottom`,元素 inline box bottom 与 parent 的 content area bottom 对齐 56 | 5. `middle`,元素 inline box 垂直中点与 parent 的 baseline 上方 0.5ex 处对齐 57 | 6. `super`,元素 content area 和 inline boex 上移,距离由用户代理确定 58 | 7. `sub`,与 super 同,下移 59 | 8. 百分比,元素上移或下移距离,百分比相对于元素的 line-height 60 | 13. `line-height` 对行高的影响(文本元素添加border等的效果) 61 | 14. 使用 `line-height` 最好方式是使用数值,为所有元素设置一样的 scale factor;字体的baseline 位置由字体本身决定,大部分字体的字符小于 em 块,一些 cursive 字体例外,会大于 em 块 62 | 15. inline 元素的 border 是由 `font-size` 而非 line-height 控制,surround the content area 63 | 16. 添加 `padding` 可以使 `border` 远离 text 本身;`padding` 和 `border` 都不影响 line box 的创建和布局 64 | 17. CSS2.1规范 “This will cause the borders on subsequent lines to paint over the borders and text of previous lines.” 同样适用于 `background`,设置`padding` 会使 `background` 区域扩展,覆盖上一行 65 | 18. `box-decoration-break`: `slice | clone`,inline 元素被分割成多行时的分隔方式,切割还是克隆,包括 background、padding、border 等: 66 | ![](5.png) 67 | 19. 象形文字的字体实际 render 与 em box 行为 68 | 20. 替换元素具有固有的宽高,元素的 box properties:content、margins、borders、padding 用来定义 inline box,都可以生效,底部 margin 的 outline edge 与 baseline 对齐 69 | 21. 替换元素 `line-height` 不会生效,但依然具备 `line-height` 值,计算 `vertical-align` 属性值时使用,以及替换元素的后代元素 70 | 22. 块级元素中的图片,对齐baseline,导致底部可能有几 px 空白,table cell、div 等,可定义 img display block 变为块级或者设置容器 line-height 1px 71 | 23. An inline-block element relates to other elements and content as an inline box. In other words, it’s laid out in a line of text just as an image would be, and in fact, inline-block elements are formatted within a line as a replaced element. 72 | 24. inline-box width 未定义或为 `auto`,element box shrink to fit content 73 | 25. CSS is moving to a system where there are two kinds of display: **the outer display type and the inner display type**. Value keywords like `block` and `inline` represent the outer display type, which provides how the display box interacts with its surroundings. The inner display, in this case flow, describes what should happen inside the element. 74 | 75 | | Old Values | New Values | 76 | ---|------------ 77 | block | block flow 78 | inline | inline flow 79 | inline-block | inline flow-root 80 | list-item | list-item block flow 81 | 82 | As of late 2017, flow and flow-root were supported by Firefox and Chrome, but no other browsers. 83 | 84 | 26. 其他 display 属性值 85 | 27. The computed value of `display` can change if an element is floated or positioned. It can also change when declared for the root element. In fact, the values `display`, `position`, and `float` interact in interesting ways. 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # CSS权威指南(第四版) 2 | 3 | 《CSS权威指南(CSS: The Definitive Guide)》是**Eric A. Meyer**所著,第三版发布于2006年。从2012年开始,CSS权威指南的第四版开始以分章节的形式由**O'Reilly**发行,目前已经发布了十章。 4 | 5 | 《CSS权威指南(第四版)》的第一章《CSS and Documents》在O'Reilly上是免费提供的,其它章节则不是。因此,这里将提供第一章的完整翻译,其后的章节则以重点总结和摘要翻译的形式提供。 6 | 7 | 如果您喜欢本书内容,请至[此处](http://www.oreilly.com/pub/au/52)购买英文原版,期待第四版尽快发行完整版并有国内出版商引入中文版。 8 | 9 | CSS的标准更新非常快,本书的第一章写于2012年,现在来看有些内容已经略有落后,而等到第四版的中文版引入国内时,又不知何年何月了。 10 | 11 | 12 | 任何问题和反馈,欢迎到 [https://github.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN](https://github.com/Jack-Sparrow/CSS-The-Definitive-Guide-4th-zh-CN) 讨论。 13 | 14 | 15 | 16 | ### Update: 17 | 18 | 英文正式版已于 2017 年 10 月正式出版:[O'Reilly 官网](http://shop.oreilly.com/product/0636920012726.do) 19 | 20 | 亚马逊中国已经有售。 -------------------------------------------------------------------------------- /docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | * [简介](README.md) 4 | * [第一章 CSS和文档](1_CSS_and_Documents/README.md) 5 | * [Web样式历史简介](1_CSS_and_Documents/README.md#web样式历史简介) 6 | * [元素](1_CSS_and_Documents/README.md#元素) 7 | * [替换元素和非替换元素](1_CSS_and_Documents/README.md#替换元素和非替换元素) 8 | * [元素显示角色](1_CSS_and_Documents/README.md#元素显示角色) 9 | * [结合CSS和HTML](1_CSS_and_Documents/README.md#结合css和html) 10 | * [`link`标签](1_CSS_and_Documents/README.md#link标签) 11 | * [`style`元素](1_CSS_and_Documents/README.md#style元素) 12 | * [`@import`指令](1_CSS_and_Documents/README.md#import指令) 13 | * [HTTP链接](1_CSS_and_Documents/README.md#http链接) 14 | * [行内样式](1_CSS_and_Documents/README.md#行内样式) 15 | * [样式表内容](1_CSS_and_Documents/README.md#样式表内容) 16 | * [标记](1_CSS_and_Documents/README.md#标记) 17 | * [规则结构](1_CSS_and_Documents/README.md#规则结构) 18 | * [空格处理](1_CSS_and_Documents/README.md#空格处理) 19 | * [CSS注释](1_CSS_and_Documents/README.md#css注释) 20 | * [媒体查询](1_CSS_and_Documents/README.md#媒体查询) 21 | * [使用](1_CSS_and_Documents/README.md#使用) 22 | * [简单媒体查询](1_CSS_and_Documents/README.md#简单媒体查询) 23 | * [媒体类型](1_CSS_and_Documents/README.md#媒体类型) 24 | * [媒体描述符](1_CSS_and_Documents/README.md#媒体描述符) 25 | * [媒体特性描述符和值类型](1_CSS_and_Documents/README.md#媒体特性描述符和值类型) 26 | * [特性查询](1_CSS_and_Documents/README.md#特性查询) 27 | * [总结](1_CSS_and_Documents/README.md#总结) 28 | * [第二章 选择器](2_Selectors/README.md) 29 | * [基本样式规则](2_Selectors/README.md#基本样式规则) 30 | * [元素选择器](2_Selectors/README.md#元素选择器) 31 | * [声明和关键字](2_Selectors/README.md#声明和关键字) 32 | * [分组](2_Selectors/README.md#分组) 33 | * [分组选择器](2_Selectors/README.md#分组选择器) 34 | * [分组声明](2_Selectors/README.md#分组声明) 35 | * [分组一切](2_Selectors/README.md#分组一切) 36 | * [旧浏览器中的新元素](2_Selectors/README.md#旧浏览器中的新元素) 37 | * [类和ID选择器](2_Selectors/README.md#类和id选择器) 38 | * [类选择器](2_Selectors/README.md#类选择器) 39 | * [多类](2_Selectors/README.md#多类) 40 | * [ID选择器](2_Selectors/README.md#id选择器) 41 | * [决定使用Class还是ID](2_Selectors/README.md#决定使用class还是id) 42 | * [属性选择器](2_Selectors/README.md#属性选择器) 43 | * [简单属性选择器](2_Selectors/README.md#简单属性选择器) 44 | * [基于准确属性值选择](2_Selectors/README.md#基于准确属性值选择) 45 | * [基于部分属性值选择](2_Selectors/README.md#基于部分属性值选择) 46 | * [特定的属性选择器](2_Selectors/README.md#特定的属性选择器) 47 | * [忽略大小写标识符](2_Selectors/README.md#忽略大小写标识符) 48 | * [使用文档结构](2_Selectors/README.md#使用文档结构) 49 | * [理解父-子关系](2_Selectors/README.md#理解父-子关系) 50 | * [后代选择器](2_Selectors/README.md#后代选择器) 51 | * [选择子元素](2_Selectors/README.md#选择子元素) 52 | * [选择相邻兄弟元素](2_Selectors/README.md#选择相邻兄弟元素) 53 | * [选择跟随兄弟元素](2_Selectors/README.md#选择跟随兄弟元素) 54 | * [伪类选择器](2_Selectors/README.md#伪类选择器) 55 | * [组合伪类](2_Selectors/README.md#组合伪类) 56 | * [结构性伪类](2_Selectors/README.md#结构性伪类) 57 | * [动态伪类](2_Selectors/README.md#动态伪类) 58 | * [UI状态伪类](2_Selectors/README.md#ui状态伪类) 59 | * [`:target`伪类](2_Selectors/README.md#target伪类) 60 | * [`:lang`伪类](2_Selectors/README.md#lang伪类) 61 | * [否定伪类](2_Selectors/README.md#否定伪类) 62 | * [伪元素选择器](2_Selectors/README.md#伪元素选择器) 63 | * [样式化第一个字母](2_Selectors/README.md#样式化第一个字母) 64 | * [样式化第一行](2_Selectors/README.md#样式化第一行) 65 | * [`::first-letter`和`::first-line`的限制](2_Selectors/README.md#first-letter和first-line的限制) 66 | * [在元素之前或之后样式化(或创建)内容](2_Selectors/README.md#在元素之前或之后样式化或创建内容) 67 | * [总结](2_Selectors/README.md#总结) 68 | * [第三章 特度和层叠](3_Specificity_and_the_Cascade/README.md) 69 | * [特度](3_Specificity_and_the_Cascade/README.md#特度) 70 | * [声明和特度](3_Specificity_and_the_Cascade/README.md#声明和特度) 71 | * [全局选择器特度](3_Specificity_and_the_Cascade/README.md#全局选择器特度) 72 | * [ID和属性选择器特度](3_Specificity_and_the_Cascade/README.md#id和属性选择器特度) 73 | * [行内样式特度](3_Specificity_and_the_Cascade/README.md#行内样式特度) 74 | * [重要性](3_Specificity_and_the_Cascade/README.md#重要性) 75 | * [继承](3_Specificity_and_the_Cascade/README.md#继承) 76 | * [层叠](3_Specificity_and_the_Cascade/README.md#层叠) 77 | * [按重要性和来源排序](3_Specificity_and_the_Cascade/README.md#按重要性和来源排序) 78 | * [按特度排序](3_Specificity_and_the_Cascade/README.md#按特度排序) 79 | * [按顺序排序](3_Specificity_and_the_Cascade/README.md#按顺序排序) 80 | * [非CSS显示标识](3_Specificity_and_the_Cascade/README.md#非css显示标识) 81 | * [总结](3_Specificity_and_the_Cascade/README.md#总结) 82 | * [特度注意点](3_Specificity_and_the_Cascade/README.md#特度注意点) 83 | * [元素应用样式的规则](3_Specificity_and_the_Cascade/README.md#元素应用样式的规则) 84 | * [第四章 值和单位](4_Values_and_Units/README.md) 85 | * [关键字、字符串和其他文本值](4_Values_and_Units/README.md#关键字、字符串和其他文本值) 86 | * [数值和百分比](4_Values_and_Units/README.md#数值和百分比) 87 | * [距离](4_Values_and_Units/README.md#距离) 88 | * [计算值](4_Values_and_Units/README.md#计算值) 89 | * [属性值](4_Values_and_Units/README.md#属性值) 90 | * [颜色](4_Values_and_Units/README.md#颜色) 91 | * [角度](4_Values_and_Units/README.md#角度) 92 | * [时间和频率](4_Values_and_Units/README.md#时间和频率) 93 | * [位置](4_Values_and_Units/README.md#位置) 94 | * [自定义值](4_Values_and_Units/README.md#自定义值) 95 | * [第五章 字体](5_Fonts/README.md) 96 | * [第六章 文本](6_Text/README.md) 97 | * [第七章 基本视觉格式化](7_Basic_Visual_Format/README.md) 98 | --------------------------------------------------------------------------------