CSS中的优先级、继承和层叠
继承(inheritance)是从一个元素向其后代元素传递属性值所采用的机制。确定应当向一个元素应用哪些值时,用户代理不仅要考虑继承,还要考虑声明的优先级,另外需要考虑声明本身的来源。这个过程就称为层叠(cascade)
优先级(Specificity)
浏览器通过优先级来判断哪一些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类选择器组成的匹配规则
计算方法
优先级就是分配给指定的CSS声明的一个权重,它由匹配的选择器中的每一种选择器类型的数值决定。
而当优先级与多个CSS声明中任意一个声明的优先级相等的时候,CSS中最后的那个声明将会被应用到元素上。
当同一个元素有多个声明的时候,优先级才会有意义。因为每一个直接作用于元素的CSS规则总是会接管/覆盖(take over)该元素从祖先元素继承而来的规则。
下面列表中,选择器类型的优先级是递增的:
类型选择器(type selectors)和伪元素(pseudo-elements)
类选择器(class selectors),属性选择器(attributes selectors),伪类(pseudo-classes)
ID选择器
通配选择符(universal selector), 关系选择符(combinators)和否定伪类(negation pseudo-class)对优先级没有影响。
可以用如下方法计算:
对于选择器中给定的各个ID属性值,加0,1,0,0
对于选择器中给定的各个类选择器、属性选择器或伪类,加0,0,1,0
对于选择器中给定的各个元素或伪元素,加0,0,0,1
结合符和通配选择器对优先级没有贡献
1 | <h1>This is a h1 element</h1> |
1 | h1 { |
声明和优先级
一旦确定一个选择器的优先级,这个优先级将授予其所有相关声明,如:
1 | h1 { |
用户代理会将其“解组”为单独的规则:
1 | h1 { |
多个规则与同一元素匹配,而且有些声明冲突时,则需考虑优先级问题
1 | <h1>This is a h1 element</h1> |
1 | h1+p { |
通配选择器优先级
通配选择器对一个选择器的优先级没有贡献,其优先级为0,0,0,0
1 | body * p {} /* 0,0,0,2 */ |
内联样式的优先级
内联样式具有最高的优先级,对于内联样式,加1,0,0,0
1 | <h1 id="red" style="color:green;">This is another h1 element</h1> |
1 | h1#id { |
由于内联样式优先级最高,h1元素的文本还是绿色
重要声明
当在一个样式声明中使用一个!important
规则时,此声明将覆盖任何其他声明。!important
放在声明最后,分号之前
1 | <h1 class="title">This is another h1 element</h1> |
1 | h1 { |
继承(Inheritance)
基于继承机制,样式不仅应用到指定的元素,还会应用到它的后代元素
大多数框模型属性(包括外边距、内边距、背景、边框等)都不能继承
继承的值没有优先级,通配选择器的优先级也高于继承的值
1
2<h1 class="title">This is <i>a special h1</i>element</h1>
<p>This is a p element</p>1
2
3
4
5
6* {
color: red;
}
h1.title {
color: green;
}
层叠(Cascade)
层叠规则
找出所有相关的规则,这些规则都包含与一个给定元素匹配的选择器
按显式权重对应用到该元素的所有声明排序
按优先级对应用到给定元素的所有声明排序
按出现顺序对应用到给定元素的所有声明排序
按权重和来源排序
权重由大到小的顺序为:
用户的
!important
声明页面作者的
!important
声明CSS动画
页面作者的普通声明
用户的普通声明
用户代理的
!important
声明用户代理的普通声明
按优先级排序
如果向一个元素应用互相冲突的声明,而且权重相同,优先级最高的声明优先
按顺序排序
如果两个规则的权重,来源和优先级完全相同,那么使用在样式表中后出现的
按此规律,建议按照link-visited-hover-active(LVHA)的顺序声明链接样式,若只需要在未访问的链接上具有悬停样式,可采用LHVA