CSS中的优先级规则分为两大类,一类称为继承,另一类称为级联。
接下来分别介绍这两类规则与CSS优先级的关系。
关于继承,只需要记住这样一句话:被继承的CSS声明的优先级一定位于整个CSS世界的底层。
举个例子,HTML代码和CSS代码如下所示:
<p id="text">文字</p>
p::first-line { color: blue; }
#text { color: green !important; }
请问,文字颜色是
blue
还是
green
?
答案是
blue
!
这里其实比的不是选择器的优先级,而是继承与否。
color
属性是一个可继承属性,无论
<p>
元素的
color
属性如何设置,对
::first-line
伪元素而言,其都是继承属性,优先级最低,因此,最终的颜色是
blue
。
另外,如果一个CSS属性同时继承自多个元素,则DOM层级越深的元素所继承的CSS优先级越高。
例如下面这个例子,请问
<p>
元素的文字颜色是
red
还是
green
?
<!DOCTYPE html>
<html>
<body>
<p>文字颜色</p>
</body>
</html>
:root { color: red; }
body { color: green; }
没错,是
green
!
<body>
元素的DOM层级比
<html>
深,因此,最终的文字颜色是
body
标签设置的属性值
green
。
以上就是继承在CSS声明的优先级中扮演的角色,还是很浅显易懂的。接下来介绍级联,做好心理准备,级联中所包含的优先级规则要复杂得多,当然,要学习的东西也更多。
级联既是概念也是模块,其优先级高于继承,包含了几乎所有CSS优先级的知识。
很多人会认为,CSS的优先级呈线性关系:我比你高,你比我低,我们一起在一个“大染缸”里。
其实并非如此,CSS的优先级是分层的,就像一层层的建筑,每一层就像一个封闭的小宇宙,与其他层互不关联,其优先级也无法超越。
具体某个CSS声明归属于其中某一层的某一个房间,这种分层加嵌套的关系就称为级联。
在CSS的继承与级联规则中,级联层的优先级定义为以下10项。
(1)
transition
过渡声明;
(2)设置了
!important
的浏览器内置样式;
(3)设置了
!important
的用户设置的样式;
(4)
@layer
规则中设置的包含
!important
的样式;
(5)开发者设置的包含
!important
的样式;
(6)
animation
动画声明;
(7)开发者设置的CSS样式;
(8)
@layer
规则中的CSS样式;
(9)用户设置的CSS样式;
(10)浏览器内置的CSS样式。
其中,出现了两个CSS属性,一个是
transition
过渡声明,另一个是
animation
动画声明。这两个级联层规则可以忽略,原因在于以下两方面。
一方面,对于
transition
过渡声明,规则中称其优先级最高,位于顶级,但是无论如何测试它都是一个普通的CSS属性行为,并不具有规则所称的具有顶级的层级。
另一方面,对于
animation
动画声明,在规则中,其优先级低于
!important
属性,但是实际测试结果却不是这样的:除Firefox浏览器之外的所有浏览器,包括Chrome、Safari、Edge甚至IE浏览器,其
@keyframes
规则中的CSS优先级都高于
!important
。
此外,(2)~(5)项和
!important
相关的规则与(7)~(10)项是有对应关系的,因此,我们需要重点关注的就是最后4项级联规则。
首先是浏览器内置样式,官方说法叫作“用户代理样式”,其实指的就是浏览器默认对一些HTML元素进行的样式设置。
例如图2-2所示的效果,在右上角会有
user agent stylesheet
的标识,中文版显示的是“用户代理样式表”。
然后是用户设置样式,这指的是用户通过某些行为带来的样式,例如浏览器自身提供的样式设置选项,或者是安装了某个浏览器插件。
图2-3展示的就是某个Chrome插件注入的样式代码,在右上角会有
injected
stylesheet
字样,中文版显示的是“注入样式表”。
图2-2 浏览器内置的样式示意
图2-3 用户设置的样式示意
至于
@layer
规则,由于其内容比较重要且知识点较多,2.2节会专门介绍。
最后是开发者设置的样式,其实就是Web前端开发人员日常所写的CSS代码,无论是内联在HTML中的CSS还是CSS文件中的代码,都属于这个级联层,其示意如图2-4所示。
图2-4 开发者设置的样式示意
上面4种类型的样式分属于不同的级联层,其优先级顺序为:
日常开发代码
>@layer
开发代码>插件注入代码>浏览器内置代码。
开发者设置的级联层优先级最高,浏览器内置的级联层的优先级最低。每个层级中的任何CSS的优先级都不可能比它上面的层级高。
因此,当要比较两段CSS代码中哪个优先级更高的时候,不是先看选择器的优先级,而是先看级联层的优先级。