CSS - 选择器优先级介绍
特殊性
从CSS选择器文章中我们知道,与多种不同的方法选择元素。所以当我们使用多种规则的时候,我们必须要明确其中的优先级。但是在CSS选择器的规则中,称之为特殊性,特殊性越高,自然优先级越高。
此时我们会先得到一个特殊性说明:
- !important 特殊性最高,详情访问重要性
- 对于内联样式,加1000
- 对于选中器中给定的ID属性值,加0100
- 对于选择器中给定的类属性值,属性选择或伪类,加0010
- 对于选择器中给定的元素选择器和伪元素,加0001.
- 结合符和通配符选择器对特殊性没有任何贡献,0000
我们还是通过举例说明上面的情况,亲自去测试一下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#ID-selector {
font-size: 10px;
}
.class-selector {
font-size: 12px;
}
*[proprty-selector] {
font-size: 14px;
}
*:first-child {
font-size: 16px;
}
div {
font-size: 18px;
}
* div {
font-size: 20px;
}
div::first-line {
font-size: 22px;
}
* {
font-size: 24px;
}
</style>
</head>
<body>
<div style="font-size: 6px;" proprty-selector="true" id="ID-selector" class="class-selector">
测试CSS选择器的特殊性
</div>
</body>
</html>
看这个例子之前先明确两点:
- 当选择器出于同一种特殊性的时候,位于css文件下部的样式会覆盖上面的样式。
- 通配符选择器对于特殊性没有任何贡献,所以下面我用了许多的通配符(强烈说明日常开发最好不要使用过多通配符,这里只是为了举例子)来代替div属性,是因为要将div自身的特殊性影响排除。
可以看到我们的css文件代码书写的顺序是按照我最上面图的顺序去加的样式,所以现在我们对照上图中红色框的样式来对比,如果是处于同一层级,那么下面的css样式会覆盖上面的css样式。
现在我们的到的特殊性的顺序是:
内联样式 > ID选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 元素选择器 = 关系选择器 = 伪元素选择器 > 通配符选择器
说明:伪元素选择器的顺序说明请看(3)
(1)对于顺序中有两部分存在等于号的,因为红色框中匹配样式的顺序与我写的代码的顺序相反,所以他们之间是平级的,所以导致代码后面的css样式覆盖了代码前面的样式(因为css的解析是从上面往下的)。
(2)我们再来说一下一开始谈到的特殊性说明中的:结合符和通配符选择器对特殊性没有任何贡献,0000, 对于通配符就是这样定义的,对于结合符说的是什么呢?说的就是关系选择器中几种通过文档结果父子关系进行的选择器。所以代码的中* div的特殊性还是和元素选择器相同。
(3)相信大家可以看到上面的红色框最后有一个伪元素的样式应用起来。看起来好像伪元素的优先级很高啊,比内联样式的优先级好高。其实呢不是这样的?我现在将上面的例子修改伪元素的样式:
*::first-line {
font-size: 22px;
}
接下来就要借助IE浏览器了,因为在chorme浏览器看不到我想要的结果。
相信大家已经看到红色框中结果了,是的现在我们可以看到伪元素选择器存在元素的样式上面,而且位于元素选择器和关系选择器的上面。
但是现在我们只解决一个问题,虽然得到了样式的顺序,可是为什么html还是应用了伪元素的样式,请看下图我们可以看到随着我取消/添加伪元素的样式,html的字体会相应的变化。这里原因如下:
伪元素的样式应用是相当于添加一个元素,这里就是添加了一个<first-line>元素在div中,然后由于字体的样式是可以继承(继承相关的内容可以访问文章)的,所以当前first-line中的样式集成了父元素的first-line的字体为22px的样式。可能你会问就算继承为什么不是继承最终的内联样式的属性,这里可能就是伪元素的规则了。
重要性
上面提到的是一般情况下,当然如果对于很复杂的页面样式来说,可能你想讲之前的所有样式都覆盖,那么就需要使用特殊手段了。有时某个声明可能非常重要,超过了所有其他声明,CSS2.1称之为重要声明。重要声明在声明的结束分号之前插入!important来标志,如果!important放在声明的任何其他位置,整个声明都将无效
如果一个声明是重要声明,则超过所有的非重要声明。现在我们将上面的例子中的通配符样式加上重要说明:如下
#ID-selector {
font-size: 10px;
}
.class-selector {
font-size: 12px;
}
*[proprty-selector] {
font-size: 14px;
}
*:first-child {
font-size: 16px;
}
div {
font-size: 18px;
}
* div {
font-size: 20px;
}
*::first-line {
font-size: 22px;
}
* {
font-size: 24px !important;
}
然后我们看一下当前的页面展示效果,可以看到现在应用到的是通配符的属性。
继承
上面已经提到一次继承。这里我们再来看继承的相关知识。对于的继承的总结可以访问继承
继承是从一个元素向其后代元素传递属性值所采用的机制。基于继承机制,样式不仅可以应用到指定的元素,还会应用到它的后代元素。在两个比较特殊的情况需要注意:一个是在HTML中,应用到body元素的背景样式可以传递到html元素;另一个是<a>标签不会继承父元素的文本样式
继承的属性没有特殊性,所以当我们对于元素进行添加选择器的时候,会直接覆盖掉继承来的属性。
继承是CSS中最基本的内容之一,除非有必要的理由,否则一般不会去考虑。
具体的继承可以查看文章(https://blog.csdn.net/it_rod/article/details/61618376#t3)
通配符具有特殊性,虽然特殊性是0,但是还是比继承高的。
层叠
最重要的来了,因为一般我们的开发中不会只有简单的样式,而是很多的样式在一起,那么我们就需要一个规则去辨别最后渲染的样式。
CSS层叠样式表的层叠特性就是让样式层叠在一起,通过特殊性、重要性、来源及继承机制来排列层叠样式的顺序及选出胜出者。
1、重要性和来源需要同时考虑,因为二者的结合使用与否会存在不同的顺序
(1) 不考虑来源的情况下,!important最高。(2) 在不考虑重要性的前提下,来源优先级顺序为:
- 读者的重要声明
- 创作人员的重要声明
- 创作人员的正常声明
- 读者的正常声明
- 用户代理声明
user(用户)!important > author(作者)!important > author > user > user agent
简单解释一下:这里说的是我们通过浏览器设置用户css样式的情况下爱,至于如何设置用户样式可以查看文章
举个例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
<div>
测试CSS声明。
</div>
</body>
</html>
/* index.css: author's style sheet */
div {
font-size: 14px;
}
div {
font-size: 16px !important;
}
/* user.css: user's style sheet */
div {
font-size: 8px;
}
div {
font-size: 10px !important;
}
我们可以看到上面有两个css文件,但是我们文件中只使用了index.css文件,这个就是创作人员的声明,对于user.css就是我们即将需要操作的user声明。
从上面的操作中可以看到,在没有应用user.css的时候,页面上的文字大小为16px,但是当我们将user.css的样式应用之后,可以看到当前页面的样式变为10px。这里的原因就是上面给的优先级顺序决定的。
2、接着,对于非重要声明来说,按照特殊性排序。特殊性越高的规则,权重越大
3、最后,如果特殊性相同,则按照出现顺序排序。声明在样式表或文档中越靠后出现,权重越大。如果样式表中有通过@import导入的样式表,一般认为出现在导入样式表中的声明在前,主样式表的所有声明在后。上一篇: 一个空格引发的“*“
下一篇: css选择器优先级