我们都知道,css中可以使用多种不同的方法选择元素。可能同一个元素可以使用两个或多个规则来选择,每个规则都有其自己的选择器。当对同一个元素应用多个选择器规则时,用户代理(浏览器)使用层叠的方式来最终展示。
特殊性
对于每个规则,用户代理(浏览器)会计算选择器的特殊性,并将这个特殊性附加到规则中的各个声明。如果同一个元素有两个或者多个冲突的属性声明时,那么有最高特殊性的声明就会胜出。
特殊性值使用4个部分表示,0,0,0,0。一个选择器的具体特殊性如下计算:
- 元素內联样式规则声明,加1,0,0,0。
- 对于选择器中给定的各个ID属性值,加0,1,0,0。
- 对于选择器中给定的各个类属性值(class),属性选择(attribute)或者伪类,加0,0,1,0。
- 对于选择器中给定的各个元素(element)或者伪元素,加0,0,0,1。
- 通配符(*)的特殊性为0,0,0,0
- 继承样式的特殊性无,并不是0,0,0,0。
从上可以得出:內联 > ID选择 > class选择|attribute选择|伪类选择 > element选择 > 通配符选择 > 继承
例如下面的例子:
h1 { color: red; } //特殊性为:0,0,0,1
p em { color: purple; }//特殊性为:0,0,0,2 因为p,em都是元素选择器,累加
.grape { color: purple; }//特殊性为:0,0,1,0
*.bright { color: yellow; }//特殊性为:0,0,1,0 因为通配符特殊性为0,0,0,0
#id216 { color: blue; }//特殊性为:0,1,0,0
p.bright em.dark { color: maroon; }//特殊性为:0,0,2,2。2个元素,2个类
div#sidebar *[href] { color: silver; }//特殊性为:0,1,1,1
假如一个em
元素即与上例中第2条规则匹配,又与第6条匹配,则这个em
将会显示maroon颜色,因为第6条的特殊性大于第2条的特殊性。
注意:元素继承的属性的特殊性是没有的,甚至连0特殊性都没有。例如下面的例子:
* { color : gray; }
h1#page-title { color: black; }
<h1 id="page-title"> Hello <em> http://www.snayan.com </em> </h1>
上面em
内容将显示gray颜色,因为通配符(*)的特殊性为0,0,0,0;而继承h1
的特殊性无。特殊性为0的规则声明 > 没有特殊性的规则声明。
重要性
有时某个声明的规则样式可能非常重要,超过了所有其他声明,则允许在这个重要的声明的结束分号之前插入!import
来标识。必须正确的放置 !import
,否则声明将无效。
标志为!import
的声明并没有特殊的特殊性值,不过它要与非重要声明分开考虑。实际上,所有的!import
声明会分组在一起,重要声明的特殊性冲突会在重要声明内部解决,而不会与非重要声明相混。类似的,我们把所有非重要声明放在一组,内部冲突内部解决。如果,一个重要声明和一个非重要声明冲突,则总是重要声明胜出。
层叠
上面讨论了用户代理(浏览器)通过特殊性值来选择为元素应用样式。但是,如果一个元素的同时匹配了特殊性值相等的2个规则,例如下面的规则声明,那将如何解决这个冲突呢?解决办法就是下面说的层叠规则了。
h1 { color :red; }
h1 { color: yellow; }
css层叠规则:
- 找出所有相关的规则,这些规则都包含与一个给定元素匹配的选择器。
- 按照显示权重对该元素的所有声明排序。标志
!import
的规则声明显示权重要高于非重要规则声明。 - 按照特殊性值对该元素的所有声明排序。特殊性值大的高于特殊性值小的规则声明。
- 按照规则声明出现的先后顺序对该元素的所有声明排序。后出现的规则声明高于先出现的规则神明。