第三章:优先级和层叠
3.1 优先级
优先级就是分配给指定的CSS声明的一个权重,由选择器的本身组成决定,一个优先级由4部分构成,例如(0, 0, 0, 0)。
选择器的优先级有以下规则:
- ID选择器为
0, 1, 0, 0。 - 类选择器,属性选择器,伪类为
0, 0, 1, 0。 - 每个元素选择器,伪元素为
0, 0, 0, 1。 - 连接符和通配选择器不增加优先级(通配选择器的优先级为
0, 0, 0, 0,而连接符没有优先级)。 - 行内样式的优先级为
1, 0, 0, 0。
比如:
h1 {color: red;} /* 优先级 = 0, 0, 0, 1 */
p em {color: red;} /* 优先级 = 0, 0, 0, 2 */
.warning {color: red;} /* 优先级 = 0, 0, 1, 0 */
*.warning.up {color: red;} /* 优先级 = 0, 0, 2, 0 */
div#main {color: red;} /* 优先级 = 0, 1, 0, 1 */
div#main *[href] {color: red;} /* 优先级 = 0, 1, 1, 1 */
如果两个或多个属性声明有冲突,那么优先级高的会胜出。
em {color: red;} /* 优先级 = 0, 0, 0, 1 */
p em {color: red;} /* 优先级 = 0, 0, 0, 2 (胜出)*/
声明和优先级
选择器的优先级确定后,将被赋予关联的每个声明。
比如:
h1 {
color: red;
backgroud: black;
}
/* 将被视为: */
h1 {color: red;}
h1 {backgroud: black;}
如果多个规则匹配同一个用啥,那么优先级就起作用了。
比如:
h1 + p {color: red;}/* 优先级 = 0, 0, 0, 2 */
.side{color: green;}/* 优先级 = 0, 0, 1, 0 */
p{color: blue;}/* 优先级 = 0, 0, 0, 1 */
对于文档:
<h1>这个是h1</h1>
<p class='side'>这是一个段落</p>
结果为:

通配选择器和连接符的优先级
通配选择器优先级为0, 0, 0, 0,连接符不存在优先级。
ID选择器和属性选择器的ID属性的优先级
ID选择器和属性选择器的ID属性的优先级是不同的,ID选择器的优先级为0, 1, 0, 0;而属性选择器的ID属性的优先级为0, 0, 1, 0。
行内样式的优先级
行内样式的优先级为1, 0, 0, 0,所有行内样式具有最高的优先级。
例外的 !important 规则
当在一个样式声明中使用一个!important 规则时,此声明将覆盖任何其他声明。虽然技术上!important与优先级无关,但它与它直接相关。
比如:
h1 + p {color: red;}/* 优先级 = 0, 0, 0, 2 */
.side{color: green;}/* 优先级 = 0, 0, 1, 0 */
p{color: blue !important;}/* 优先级 = 0, 0, 0, 1 */
对于文档:
<h1>这个是h1</h1>
<p class='side'>这是一个段落</p>
结果为:

3.2 继承
继承指某些样式不仅应用到所指的元素,还应用到元素的后代上。
在CSS中,每个CSS属性定义的概述都指出了这个属性是默认继承的(“Inherited: Yes”) 还是默认不继承的(“Inherited: no”)。这决定了当你没有为元素的属性指定值时该如何计算值。
继承是CSS的根基之一,哪些属性默认被继承哪些不被继承大部分符合常识,通常无需考虑。但是需要注意的是:
继承的值没有优先级。(所以继承属性和通配选择器有冲突时候,通配选择器胜出)。
比如以下CSS设置:
* {color: red;}
h1#title {color: black;}
对于文档:
<h1 id="title">
h1标题<em>倾斜的em</em>
</h1>
结果为:

3.3层叠
层叠是CSS的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。它在CSS处于核心地位,CSS的全称层叠样式表正是强调了这一点。
CSS声明可以有不同的来源:
- 浏览器会有一个基本的样式表来给任何网页设置默认样式。这些样式统称用户代理样式。
- 网页的作者可以定义文档的样式,这是最常见的样式表。
- 读者,作为浏览器的用户,可以使用自定义样式表定制使用体验。
层叠规则
-
首先过滤来自不同源的全部规则,并保留要应用到指定元素上的那些规则。
-
依据重要性对这些规则进行排序。即是指,规则后面是否跟随者
!important以及规则的来源。层叠是按升序排列的,这意味着来着用户自定义样式表的!important值比用户代理样式表的普通值优先级高:重要性(从低到高) 来源 重要程度 1 用户代理 普通 2 用户代理 !important3 用户 普通 4 页面作者 普通 5 CSS动画 见下节 6 页面作者 !important7 用户 !important -
假如层叠顺序相等,则使用哪个值取决于优先级。
CSS动画与层叠
CSS动画,指使用@keyframes @规则定义状态间的动画。关键帧不参与层叠,意味着在任何时候CSS都是取单一的@keyframes的值而不会是某几个@keyframe的混合。
当有多个满足条件的关键帧时,在最重要的文档里面最后定义的关键帧会被选中,而不会是将它们组合在一起。
同时仍应注意用@keyframes @规则定义的值会覆盖全部普通值,但会被!important的值覆盖。
例子
用户代理CSS:
li { margin-left: 10px }
网页作者CSS1:
li { margin-left: 0 }
网页作者CSS2:
@media screen {
li { margin-left: 3px }
}
@media print {
li { margin-left: 1px }
}
用户CSS:
.specific { margin-left: 1em }
HTML:
<ul>
<li class="specific">1<sup>st</sup></li>
<li>2<sup>nd</sup></li>
</ul>
对于这个情形,应当应用li和.specific里面的声明。由于没有声明被标记为!important,所以优先顺序为页面作者样式优于用户样式,用户代理样式最低。
故是这3条声明的竞争:
margin-left: 0
margin-left: 3px
margin-left: 1px
由于是在屏幕显示,所以最后一条舍弃,而前两条的选择器相同,因此优先级也相同,故最终选择的是后者:
margin-left: 3px
注意尽管定义在用户CSS里面的声明有更高的优先级,但它并不会被选中,因为层叠算法是先于优先级算法的。