7.3 层叠:当规则发生冲突时
很多地方都可以应用样式。正如你在第1章中学到的,每个浏览器都有其默认样式。不过,你可以用自己的样式覆盖它们或对它们进行补充。应用样式有三种方式:从一个或多个外部文件导入(推荐),如图7.3.1中的代码所示,插入到HTML文档的顶部,或直接应用于代码中特定的元素上(不过,应该尽可能地避免这样做)。下一章将对这三种方式做具体讲解。
- p {
- color: #36c;
- font-family: "Trebuchet MS", "Helvetica", sans-serif;
- font-weight: bold;
- }
- img {
- float: left;
- margin-right: 10px;
- }
图7.3.1 这是图7.3.2中HTML文档的样式表。现在不需要关心太多的细节,只需要意识到这里有一条关于p
元素(而不是h1
、em
或small
元素)的规则
同时,一些浏览器还允许访问者创建他们自己的样式表,并将其应用于他们所访问的页面(包括你的页面)。此外,有一些样式是由子元素继承自父元素的。
你可能会问,对某一给定元素应用多条样式规则时,会发生什么情况?CSS用层叠的原则来考虑继承(inheritance)、特殊性(specificity)和位置(location)等重要特征,从而判断相互冲突的规则中哪个规则应该起作用。
我们从继承开始讨论。很多CSS属性不仅影响选择器所定义的元素,而且会被这些元素的后代继承(参见图7.3.1、图7.3.2和图7.3.3)。例如,假设要让所有的h1
元素显示为蓝色,并带有红色边框。不过,color
属性是继承的,而border
属性不是。那么,h1
元素里包含的任何元素都会是蓝色的,但不会有红色的边框。你将在描述每个属性的章节(以及附录B)了解到哪些属性是继承的。另外,对大多数属性来说,还可以使用inherit
值强制进行继承(参见7.4节)。
- ...
- <body>
- <h1>The Ephemeral Blue Flax</h1>
- <img src="img/blueflax.jpg" width="300" height="175" alt="Blue Flax (Linum lewisii)" />
- <p>I am continually <em>amazed</em> at the beautiful, delicate Blue Flax that somehow took hold in my garden. They are awash in color every morning, yet not a single flower remains by the afternoon. They are the very definition of ephemeral.</p>
- <p><small>© by Blue Flax Society. </small></p>
- </body>
- </html>
图7.3.2 em
和small
元素包含在p
元素里,因此它们是p
的子元素。不过,h1
并不是p
的子元素,因此它不像其他文本一样是蓝色的,参见图7.3.3
图7.3.3 图7.3.1中并没有显式地指定em
和small
元素的样式,它们将从其父元素p
那里继承字体、粗体和颜色。斜体来自浏览器为em
设的默认样式。出于同样的原因,由small
(表示法律“细则”)标记的法律通告的字号要比普通文本的小。h1
本身没有设置样式,它也不是p
的子元素,因此它完全根据浏览器的默认样式进行显示
继承决定了一个元素没有应用任何样式时应该怎样显示,而特殊性则决定了应用多个规则时应该怎样显示(参见图7.3.4、图7.3.5和图7.3.6)。根据特殊性原则,选择器越特殊,规则就越强。讲得通,对吧?因此,如果一条规则声明所有的h1
元素都应该是蓝色的,而另一条规则声明所有class
为spanish
的h1
元素都应该是红色的,那么对于所有class
为spanish
的h1
元素,第二条规则将覆盖第一条规则,因为h1.spanish
是比h1
更为特殊的选择器。
p {
color: red;
}
p.group {
color: blue;
}
p#last {
color: green;
}
p#last {
color: magenta;
}
图7.3.4 在这个例子中,有四个具有不同特殊性的规则。第一个影响所有p
元素,第二个只影响class
为group
的p
元素,而第三个和第四个则只影响id
为last
的唯一的p
元素
注意,id
属性被认为是最特殊的(因为它们在一个文件中必须是唯一的),而带class
属性的选择器则比不带class
的更特殊。同时,具有多个class
的选择器比只有一个class
的更特殊。在特殊性次序中,最低级的是只有元素名的选择器,这时继承的规则被认为是最一般的,可以被任何其他规则覆盖。
关于特殊性计算的精确规则,参见CSS规范6.4.3节(www.w3.org/TR/CSS21/cascade.html#specificity)。
- ...
- <body>
- <p>Here's a generic <code>p</code> element. It will be red.</p>
- <p class="group">Here's a <code>p</code> element with a <code>class</code> of <code>group</code>. There are two rules that apply, but since the <code>p.group </code> rule is more specific, this paragraph will be blue.</p>
- <p id="last" class="group">Here's a <code> p</code> element with an <code>id</code> of <code>intro</code>. There are four rules that could apply to this paragraph. The first two are overruled by the more specific last two. The position breaks the tie between the last two: the one that appears later wins, and thus this paragraph will be magenta.</p>
- </body>
- </html>
图7.3.5 这里有三个段落:一个是一般的,一个是带有一个class
的,一个是同时带有一个class
和一个id
的。
图7.3.6 由于第三个和第四个规则具有相同的特殊性,位置就成为一个考虑因素。由于第四条规则最后出现,因此它的优先级更高
有时候,特殊性还不足以判断在相互冲突的规则中哪一个应该优先。在这种情况下,规则的位置就可以起到决定的作用:晚出现的优先级高(参见图7.3.4、图7.3.5和图7.3.6)。例如,直接应用在HTML元素上的规则(再说一遍,这种做法不推荐使用)被认为比外部样式表中或插在HTML文档顶部的特殊性相同的规则出现得更晚(因此优先级更高)。详细信息参见8.5节。
如果这还不够,那么还可以在某条规则的末尾加上!important
,以声明这个规则比其他规则更重要,超过整个优先级体系(除少数情况以外,这种做法也不推荐使用)。
总之,在没有规则的时候,很多样式都从父元素传递到子元素。当两个规则发生冲突时,规则更特殊的优先级(即重要性)更高(如果不考虑位置的话)。如果两个规则的特殊性相同,则晚出现的优先级更高。
如果感觉这些东西还是很费解,也不必担心。一旦你真正开始使用CSS以及不同的选择器,你会发现,在大多数情况下,层叠会像你预期的那样运行。