现在的位置: 首页 > 综合 > 正文

层叠和特殊性

2013年10月20日 ⁄ 综合 ⁄ 共 2845字 ⁄ 字号 评论关闭

即使在不太复杂的样式表中,要寻找同一元素可能有两个或更多规则。CSS通过一个称为层叠(cascade)的过程处理这种冲突。层叠给每个规则分配一个重要度。作者的样式表是由站点开发者编写的,被认为是最重要的样式表。用户可以通过浏览器应用自己的样式,这些样式表的重要度低一级。最后是浏览器或用户代理使用的默认样式表,它们的重要度是最低的,所以你总是可以覆盖它们。为了让用户有更多的控制能力,可以通过将任何规则指定为!important来提高它的重要度,让它优先于任何规则,甚至优先于作者加上!important标志的规则。这种设置能够满足特殊的可访问性需求,例如如果用户有某种读写障碍,可以使用中等对比度的用户样式表。

因此,层叠采用以下重要度次序。

标有!important的用户样式。

标有!important的作者样式。

作者样式。

用户样式。

浏览器/用户代理应用的样式。

然后,根据选择器的特殊性决定规则的次序。具有更特殊选择器的规则优先于具有一般选择器的规则。如果两个规则的特殊性相同,那么后定义的规则优先。

1. 特殊性

为了计算规则的特殊性,给每种选择器都分配一个数字值。然后,将规则的每个选择器的值加在一起,计算出规则的特殊性。可惜特殊性的计算不是以10为基数的,而是采用一个更高的未指定的基数。这能确保非常特殊的选择器(比如ID选择器)不会被大量一般选择器(比如类型选择器)所超越。但是,为了简化,如果在一个特定选择器中的选择器数量少于10个,那么可以以10为基数计算特殊性。

选择器的特殊性分成4个成分等级:a、b、c和d。

如果样式是行内样式,那么a = 1。

b等于ID选择器的总数。

c等于类、伪类和属性选择器的数量。

d等于类型选择器和伪元素选择器的数量。

使用这些规则可以计算任何CSS选择器的特殊性。表2-1给出了一系列选择器以及相应的特殊性。

表2-1 特殊性示例

选 择 器

特 殊 性

以10为基数的特殊性

Style=""

1,0,0,0

1000

#wrapper #content {}

0,2,0,0

200

#content .datePosted {}

0,1,1,0

110

div#content {}

0,1,0,1

101

#content {}

0,1,0,0

100

p.comment .dateposted {}

0,0,2,1

21

p.comment{}

0,0,1,1

11

div p {}

0,0,0,2

2

p {}

0,0,0,1

1

初看上去,上面的特殊性和更高的未指定的基数可能有点儿让人糊涂,所以再解释一下。基本上,用style属性编写的规则总是比其他任何规则特殊。具有ID选择器的规则比没有ID选择器的规则特殊,具有类选择器的规则比只有类型选择器的规则特殊。最后,如果两个规则的特殊性相同,那么后定义的规则优先。

在修复bug时特殊性极其重要,因为你需要了解哪些规则优先及其原因。例如,假设有以下这组规则,你认为两个标题会是什么颜色的?

  1. #content div#main-content h2 {
  2. color: gray;
  3. }
  4. #content #main-content>h2 {
  5. color: blue;
  6. }
  7. body #content div[id="main-content"] h2 {
  8. color: green;
  9. }
  10. #main-content div.news-story h2 {
  11. color: orange;
  12. }
  13. #main-content [class="news-story"] h2 {
  14. color: yellow;
  15. }
  16. div#main-content div.news-story h2.first {
  17. color: red;
  18. }
  19. <div id="content">
  20. <div id="main-content">
  21. <h2>Strange Times</h2>
  22. <p>Here you can read bizarre news stories from around the globe.</p>
  23. <div class="news-story">
  24. <h2 class="first">Bog Snorkeling Champion Announced Today</h2>
  25. <p>The 2008 Bog Snorkeling Championship was won by Conor Murphy
  26. with an impressive time of 1 minute 38 seconds.</p>
  27. </div>
  28. </div>
  29. </div>

令人吃惊的是,两个标题都是灰色的。第一个选择器由两个ID选择器组成,因此它具有最高的特殊性。后面一些选择器看起来更复杂,但是因为它们只包含一个ID,所以特殊性总是低于第一个选择器。

如果你遇到了似乎没有起作用的CSS规则,很可能是出现了特殊性冲突。请在你的选择器中添加它的一个父元素的ID,从而提高它的特殊性。如果这能够解决问题,就说明样式表中其他地方很可能有更特殊的规则,它覆盖了你的规则。如果是这种情况,你可能需要检查代码,解决特殊性冲突,让代码尽可能简洁。

2. 在样式表中使用特殊性

在编写CSS时特殊性非常有用,因为它可以对一般元素应用一般样式,然后在更特殊的元素上覆盖它们。例如,如果你希望站点上大多数文本是黑色的,但介绍说明文本是灰色的。可以这样做:

  1. p {color: black;}
  2. p.intro {color: grey;}

对于小网站,这很好。但是,在大型站点上,你会发现例外情况越来越多。例如,你可能希望新闻文章上的介绍文本是蓝色的,而主页上的介绍文本使用灰色背景。每当创建更特殊的样式时,可能需要覆盖一些一般规则。这可能需要一些额外的代码。而且,因为元素可以从许多地方获得样式,情况可能变得非常复杂。

为了避免过分混乱,我尽量保持一般性样式非常一般,特殊样式尽可能特殊,这样就不需要覆盖特殊样式了。如果发现不得不多次覆盖一般样式,那么从更一般的规则中删除需要覆盖的声明,并且将它显式地应用于需要它的每个元素,这样可能比较简单。

3. 在主体标签上添加类或ID

一种有意思的特殊性用法是在主体(body)标签上应用类或ID。这样做之后,就可以根据页面或在站点范围内覆盖样式。例如,如果希望新的页面具有特殊的布局,那么可以在主页的主体元素上添加一个类名,并且使用它覆盖样式:

  1. body.news {
  2. /* do some stuff */
  3. }
  4. <body class="news">
  5. <p>My, what a lovely body you have.</p>
  6. </body>

有时候,在特殊页面上需要覆盖这些样式,比如在新闻存档页面上。在这种情况下,可以在主体标签上添加ID来标识这个页面。

  1. body.news {
  2. /* do some stuff */
  3. }
  4. body#archive {
  5. /* do some different stuff */
  6. }
  7. <body id="archive" class="news">
  8. <p>My, what a lovely body you have.</p>
  9. </body>

使用类标识页面类型,使用ID标识特定页面,就可以非常灵活地控制站点的设计和布局。我很喜欢使用这种方法编写可维护的代码。

抱歉!评论已关闭.