一般情况下,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的优先级特性来解释了。关于这个,可以看一幅很直观的图。
从上图中可以看到采用style定义的内联CSS样式优先级最高,然后是ID,类,最后才是html元素。
然后我们可以根据这图来判断给定的样式的优先值为如何的了。方法很简单,找出各个优先级的个数,然后按照上图的位置填下去就可以了。至于优先级的比较,从优先级由高到低,大者优先,相等则比较下一个优先级,依此下去。
下面是一些例子
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,应该字体是红色,但结果却是蓝色。
当然,这种极端的情况几乎不会出现,但应该对优先级有着正确的理解。
有了以上资料,就不难解决此文开始的问题了。
参考
- Specifics on CSS Specificity(此文所有图片皆来自此)
- CSS的优先级特性Specificity