css2.0对权重描述的并不是很清楚,但是在CSS2.1里W3C已经对CSS的权重有了明确的规定。
- Media type and element match
- Importance and origin in ascending order of importance (confusingly):
- user agent style sheets
- user normal style sheets
- author normal style sheets
- author important style sheets
- user important style sheets
- Specificity
- Source order
这里面最重要的就是3.Specificity特异性,我把他翻译为权重。
权重是样式表的精髓,它也是样式表时时刻刻在做的事情,是它决定元素该用那个规则而不用哪个规则。在它做决定一起,它要参考几样东西:规则的特殊性,规则的来源,规则出现的顺序。这几样东西的先后顺序,也就是左右它决定的先后顺序。也就是说,它们在帮助层叠做决定的过程中,扮演的优先级别是:特殊性》来源》顺序。只有在前一项一致的情况才去考虑后者。也就是说当几个规则的特殊性一致,才去考虑他们的来源是否一直,是否可以决定用哪条规则,如果来源也一样的话,就只剩下用出现的顺序,来决定最终的胜出者。权重有他自己的一套计算理论和表达方式,下面,我们就来分别说一下他们各自的优先级别:
权重值示图:
对它的解释就是:
1.权重值是从左向右读的,所以左边的总是大于右边,最左边只有一个1,都大于最右边是99的,即1,0,0,0>0,0,0,99
2.权重值是在各自位置叠加得出的最终值,也就是说有几个id,第二个位置上就有几个1,有几个类或属性,伪类,第三个位置就有几个1,有几个元素伪元素,第四个位置就有几个1
3.往往容易忽略的通配符的权重比继承高,因为继承没有权重值,所以在通配符里面写的样式会胜出。这里的通配符包括单写的*的,和*a等价于a,*p等价于p等等。所以,如果一个p里面有a,而你只给p有color值,p里a没有明确显示写出color,它会去找有没有*a或a在样式表里,如果你的样式表里面没有,它就会去用户代理的样式表中找,这就是为什么当p{color:red;}时,p里面的a不是red,而是其他颜色的原因。
也许你看了上面的权重图会有些疑问,为什么没有!important 的身影?那是因为,!important不论是在内联或是外联CSS样式表中,其级别都是最高级。所以!important与上面的就不是一个级别的东东,不可相提并论。
还有需要补充一点的是:经常有人会说ie6不支持!importan,我以前也有这个误区,后来在一个朋友的帮助下纠正啦。ie6不是不支持!important,而是支持的有些bug,就是选择器内的属性必需为唯一,不然IE6最以最后一个属性显示结果。请看下个小例子:
/*first*/ p{ color:red !important; } p{ color:blue; } /*second*/ p{ color:red !important; } #ys p{ color:blue; } /*third*/ p{ color:red !important; color:blue; }
结果只有最后一种在ie6下显示的是blue,其他都是显示red。所以可以看出ie6是支持!important,只是有点畸形而已。
来源的优先级:创造人员>读者>用户代理(浏览器)
但如果不考虑特殊性的话,优先级别这样:读者!important >创造!important >创作人员>读者>用户代理
顺序优先级:最后出现的胜出,也就是同样的一条规则,最后出现的相同权重,相同来源的规则,会覆盖前门的规则,如h1{color:red;}...h1{color:green;}则h1{color:green;}的规则胜出。
那也许你会问:样式表里面那么多的规则,根据层叠原理,用户代理到底是如何筛选众多样式中胜出的声明呢?它的机制又是怎样的?
其实,我们创作人员写规则都是把跟这个元素有关的声明,放在一个规则里去写,而不是每个声明一条规则,还有就是把相同规则应用到多个元素,而不是每个元素重复写相同的规则,这么做的好处是方便我们去写,给我们减少工作量。但用户代理不这样想,它很不领情,把我们辛辛苦苦写在一起的规则分组,全部打散成单条规则。所以,它会把我们的分组声明,规则分组里面的全部声明解体成,每条声明自成一条规则。这是第一步。第二步就是初步筛选,看看哪些规则是应用于同一个元素的,把它过滤出来。第三步就是粗筛选。看看这些规则里面有哪些声明是相互冲突的,哪些是不冲突的,把不冲突的放在一边。第四步就是精筛选,运用层叠原理对相互冲突的声明筛选,留出胜出者。第五步就是把第四步的胜出者与第三步中不冲突的声明,重新组合成一条新规则,最终作用到元素上。
下面运用层叠原理看一个例子:
h1+p{color:black;font-style:italic;}/*0,0,0,2*/ p{color:gray;background:white;font-style:normal;}/*0,0,0,1*/ *.asider{color:black;background:silver;}/*0,0,1,0*/ //结构如下: <h1>Greeting</h1> <p class="asider">It's a fine day today</p> //分析如下: //第一步和第二步: h1+p{color:black;}/*0,0,0,2*/ h1+p{font-style:italic;}/*0,0,0,2*/ p{color:gray;}/*0,0,0,1*/ p{background:white;}/*0,0,0,1*/ p{font-style:normal;}/*0,0,0,1*/ *.asider{color:black;}/*0,0,1,0*/ *.asider{background:silver;}/*0,0,1,0*/ //第三步和第四步: h1+p{color:black;}/*0,0,0,2*/ p{color:gray;}/*0,0,0,1*/ *.asider{color:black;}/*0,0,1,0*/ //胜出者 h1+p{font-style:italic;}/*0,0,0,2*/ //胜出者 p{font-style:normal;}/*0,0,0,1*/ p{background:white;}/*0,0,0,1*/ *.asider{background:silver;}/*0,0,1,0*/ //胜出者 //第五步,最终样式如下: .asider{background:silver;color:black;font-style:italic;}
以上就是我对css层叠原理的理解,如果哪些地方有什么理解错误的话,希望大家能够指正!