一般情况下,css遵循着后定义优先,越详细具体越优先的原则。不过在某些情况下,你却得不到你想要的样式。我在启用CodeColorer插件的时候,就被这一点烦恼了很久。

举个简单的例子,有以下html文本:

1
2
3
4
5
<ul id="summer-drinks">
   <li class="favorite">Whiskey and Ginger Ale  </li>
   <li>Wheat Beer  </li>
   <li>Mint Julip  </li>
</ul>

然后定义了以下的CSS样式:

1
2
3
4
5
6
7
8
9
#summer-drinks li  {
    font-weight :  normal ;
    font-size :  12px ;
    color :  black ;
}
.favorite  {
   color :  red ;
   font-weight :  bold ;
}

你期望带有类favorite的“Whiskey and Ginger Ale”能以红色粗体呈现,可结果却跟别的字体别无二样。

该如何让定义的样式起作用呢?很容易想到的就是更改一下后者的选择符,将其改为#summer-drinks .favorite,你会发现,啊,起作用了。如果不想更改选择符,可以使用!important这个金手指,即使用以下样式:

1
2
3
4
.favorite  {
   color :  red !important ;
   font-weight :  bold !important ;
}

这里的问题是解决了,可是为什么?按理说,.favorite定义更具体更靠后,应该起作用才对,可是为什么?

这就需要CSS的优先级特性来解释了。关于这个,可以看一幅很直观的图。

css specifity base

css specifity base

从上图中可以看到采用style定义的内联CSS样式优先级最高,然后是ID,类,最后才是html元素。
然后我们可以根据这图来判断给定的样式的优先值为如何的了。方法很简单,找出各个优先级的个数,然后按照上图的位置填下去就可以了。至于优先级的比较,从优先级由高到低,大者优先,相等则比较下一个优先级,依此下去。

下面是一些例子

css specifity 1

css specifity 1

css specifity 2

css specifity 2

css specifity 3

css specifity 3

css specifity 4

css specifity 4

css specifity 5

css specifity 5

Notice

关于!important

这玩意是个金手指,优先级最高,有它时优先级可以看作是1,0,0,0,0。

Pseudo-elements (e.g. ::first-line) get 0,0,0,1 unlike their psuedo-class brethren which get 0,0,1,0

The pseudo-class :not() adds no specificity by itself, only what’s inside it’s parentheses.

我看过的国内的几篇关于CSS优先级的文章,其中原理都是这样的,不过常用的说法是ID的权值是100,class的是10,element的是1,统计好个数后,然后进行算术相加,最后比较大小。
严格来说,这种说法是错的,因为其实那个优先级的表示并不是十进制的,只是表示在前的优先而已。只是,我们为了读起来和表达起来容易,常当作十进制来表示了。

一个简单的反例,定义以下样式(11个类,1个ID)

1
2
.a .b .c .d .e .f .g .h .i .j .k  {  color : red ;  }
#myel  { color : blue ; }

和html

1
<span class="a b c d e f g h i j k" id="myel">would still be blue. </span>

可以看到,如果采用10进制的话,11个class的权值是110,而1个ID只是100,应该字体是红色,但结果却是蓝色。

当然,这种极端的情况几乎不会出现,但应该对优先级有着正确的理解。

有了以上资料,就不难解决此文开始的问题了。

参考