7.3 层叠:当规则发生冲突时

很多地方都可以应用样式。正如你在第1章中学到的,每个浏览器都有其默认样式。不过,你可以用自己的样式覆盖它们或对它们进行补充。应用样式有三种方式:从一个或多个外部文件导入(推荐),如图7.3.1中的代码所示,插入到HTML文档的顶部,或直接应用于代码中特定的元素上(不过,应该尽可能地避免这样做)。下一章将对这三种方式做具体讲解。

  1. p {
  2. color: #36c;
  3. font-family: "Trebuchet MS", "Helvetica", sans-serif;
  4. font-weight: bold;
  5. }
  6.  
  7. img {
  8. float: left;
  9. margin-right: 10px;
  10. }

图7.3.1 这是图7.3.2中HTML文档的样式表。现在不需要关心太多的细节,只需要意识到这里有一条关于p元素(而不是h1emsmall元素)的规则

同时,一些浏览器还允许访问者创建他们自己的样式表,并将其应用于他们所访问的页面(包括你的页面)。此外,有一些样式是由子元素继承自父元素的。

你可能会问,对某一给定元素应用多条样式规则时,会发生什么情况?CSS用层叠的原则来考虑继承(inheritance)、特殊性(specificity)和位置(location)等重要特征,从而判断相互冲突的规则中哪个规则应该起作用。

我们从继承开始讨论。很多CSS属性不仅影响选择器所定义的元素,而且会被这些元素的后代继承(参见图7.3.1、图7.3.2和图7.3.3)。例如,假设要让所有的h1元素显示为蓝色,并带有红色边框。不过,color属性是继承的,而border属性不是。那么,h1元素里包含的任何元素都会是蓝色的,但不会有红色的边框。你将在描述每个属性的章节(以及附录B)了解到哪些属性是继承的。另外,对大多数属性来说,还可以使用inherit值强制进行继承(参见7.4节)。

  1. ...
  2. <body>
  3.  
  4. <h1>The Ephemeral Blue Flax</h1>
  5.  
  6. <img src="img/blueflax.jpg" width="300" height="175" alt="Blue Flax (Linum lewisii)" />
  7.  
  8. <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>
  9.  
  10. <p><small>© by Blue Flax Society. </small></p>
  11.  
  12. </body>
  13. </html>

图7.3.2 emsmall元素包含在p元素里,因此它们是p的子元素。不过,h1并不是p的子元素,因此它不像其他文本一样是蓝色的,参见图7.3.3

7.3 层叠:当规则发生冲突时 - 图1

图7.3.3 图7.3.1中并没有显式地指定emsmall元素的样式,它们将从其父元素p那里继承字体、粗体和颜色。斜体来自浏览器为em设的默认样式。出于同样的原因,由small(表示法律“细则”)标记的法律通告的字号要比普通文本的小。h1本身没有设置样式,它也不是p的子元素,因此它完全根据浏览器的默认样式进行显示

继承决定了一个元素没有应用任何样式时应该怎样显示,而特殊性则决定了应用多个规则时应该怎样显示(参见图7.3.4、图7.3.5和图7.3.6)。根据特殊性原则,选择器越特殊,规则就越强。讲得通,对吧?因此,如果一条规则声明所有的h1元素都应该是蓝色的,而另一条规则声明所有classspanishh1元素都应该是红色的,那么对于所有classspanishh1元素,第二条规则将覆盖第一条规则,因为h1.spanish是比h1更为特殊的选择器。

  1. p {
  2. color: red;
  3. }
  4. p.group {
  5. color: blue;
  6. }
  7. p#last {
  8. color: green;
  9. }
  10. p#last {
  11. color: magenta;
  12. }

图7.3.4 在这个例子中,有四个具有不同特殊性的规则。第一个影响所有p元素,第二个只影响classgroupp元素,而第三个和第四个则只影响idlast的唯一的p元素

注意,id属性被认为是最特殊的(因为它们在一个文件中必须是唯一的),而带class属性的选择器则比不带class的更特殊。同时,具有多个class的选择器比只有一个class的更特殊。在特殊性次序中,最低级的是只有元素名的选择器,这时继承的规则被认为是最一般的,可以被任何其他规则覆盖。

关于特殊性计算的精确规则,参见CSS规范6.4.3节(www.w3.org/TR/CSS21/cascade.html#specificity)。

  1. ...
  2. <body>
  3.  
  4. <p>Here's a generic <code>p</code> element. It will be red.</p>
  5.  
  6. <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>
  7.  
  8. <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>
  9.  
  10. </body>
  11. </html>

图7.3.5 这里有三个段落:一个是一般的,一个是带有一个class的,一个是同时带有一个class和一个id的。

7.3 层叠:当规则发生冲突时 - 图2

图7.3.6 由于第三个和第四个规则具有相同的特殊性,位置就成为一个考虑因素。由于第四条规则最后出现,因此它的优先级更高

有时候,特殊性还不足以判断在相互冲突的规则中哪一个应该优先。在这种情况下,规则的位置就可以起到决定的作用:晚出现的优先级高(参见图7.3.4、图7.3.5和图7.3.6)。例如,直接应用在HTML元素上的规则(再说一遍,这种做法不推荐使用)被认为比外部样式表中或插在HTML文档顶部的特殊性相同的规则出现得更晚(因此优先级更高)。详细信息参见8.5节。

如果这还不够,那么还可以在某条规则的末尾加上!important,以声明这个规则比其他规则更重要,超过整个优先级体系(除少数情况以外,这种做法也不推荐使用)。

总之,在没有规则的时候,很多样式都从父元素传递到子元素。当两个规则发生冲突时,规则更特殊的优先级(即重要性)更高(如果不考虑位置的话)。如果两个规则的特殊性相同,则晚出现的优先级更高。

如果感觉这些东西还是很费解,也不必担心。一旦你真正开始使用CSS以及不同的选择器,你会发现,在大多数情况下,层叠会像你预期的那样运行。