CSS选择器优先级以及复杂选择器的权重计算 - 【大前端】

CSS选择器的优先级

!important > 行间样式 > id > class|属性|伪类 > 标签选择器|伪元素 > 通配符

复杂的选择器

CSS选择器权重值主要用于复杂选择器的权重计算,一般的选择器依据优先级判断即可。

1. 父子选择器/派生选择器

1
2
3
4
5
<div>
<strong>
<em>234</em>
</strong>
</div>
1
2
3
div strong em{
background-color: red;
}

效果如下(浏览器页面放大了5倍,方便观察,下文不再特殊说明):

父子选择器不是只针对标签,也可以是类或者id,比如:

1
2
3
4
5
<div class="wrapper">
<strong class="box">
<em>234</em>
</strong>
</div>

类与标签的父子选择器

1
2
3
4
5
6
7
/*div strong em{
background-color: red;
}*/

.wrapper .box em{
background-color: green;
}

效果如下:

类、id以及标签的父子选择器

1
2
3
4
5
<div class="wrapper">
<strong class="box" id="box1">
<em>234</em>
</strong>
</div>

1
2
3
4
5
6
7
8
9
10
11
/*div strong em{
background-color: red;
}*/

/*.wrapper .box em{
background-color: green;
}*/

.wrapper #box1 em{
background-color: yellow;
}

效果如下:

父子选择器的生效范围:直接的或者间接的子选择器均生效。

1
2
3
4
5
6
<div class="wrapper">
<em>1</em>
<strong class="box" id="box1">
<em>234</em>
</strong>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*div strong em{
background-color: red;
}*/

/*.wrapper .box em{
background-color: green;
}*/

/*.wrapper #box1 em{
background-color: yellow;
}*/

div em{
background-color: red;
}

效果如下:

2.直接子元素选择器

1
2
3
4
5
6
<div class="wrapper">
<em>1</em>
<strong class="box" id="box1">
<em>234</em>
</strong>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*div strong em{
background-color: red;
}*/

/*.wrapper .box em{
background-color: green;
}*/

/*.wrapper #box1 em{
background-color: yellow;
}*/

div em{
background-color: red;
}

div > em{
background-color: green;
}

效果如下:

简单的理解是:它的生效范围仅仅为父子选择器中直接的子选择器

父子选择器的浏览器解释顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<section>
<div>
<p>
<a href="">
<span></span>
</a>
</p>
<ul>
<li>
<a href="">
<span>
<em>1</em>
</span>
</a>
<p></p>
</li>
<li></li>
</ul>
</div>

<a href="">
<p>
<em>2</em>
</p>
<div></div>
</a>
</section>
1
2
3
section div ul li a em{
background-color: red;
}

效果如下:

问题来了,父子选择器的解释到底是从左到右呢,还是从右到左呢?

假设从左到右:

因为父子选择器的生效范围包括直接和间接的子选择器,会先找所有的 section 的标签,然后再找 section 下包含了 div 的选择器,不管是间接的还是直接的,这个时候已经有两条路径了,再找 div 下的所有 ul,…… ,依次类推

假设从右到左:

对比下来,明显可以发现,从右到左的解释判断更少、路径更少,也就是解释速度更快

结论:父子选择器的浏览器解释顺序是从右到左的

3.并列选择器

1
2
3
<div>1</div>
<div class="demo">2</div>
<p class="demo">3</p>
1
2
3
div.demo{
background-color: red;
}

ps.并列选择器之间没有空格

效果如下:

4. 分组选择器

1
2
3
<em>1</em>
<strong>2</strong>
<span>3</span>
1
2
3
em, strong, span{
background-color:red;
}

效果如下:

然而在实际的开发中,css 一般用如下的写法,便于观察:

1
2
3
4
5
em, 
strong,
span{
background-color:red;
}

效果是一样的,只不过更便于阅读。

CSS选择器权重值

选择器 权重
!important Infinity
行间样式 1000
id 100
class&属性&伪类 10
标签选择器&伪元素 1
通配符 0

以上数字的进制为256进制

复杂选择器的权重计算

1
2
3
<div class="classDiv" id="idDiv">
<p class="classP" id="idP">1</p>
</div>
1
2
3
4
5
6
7
#idDiv p{
background-color: red;
}

.classDiv .classP{
background-color: green;
}

效果如下:

为什么呢?

id选择器的权重值为100,class选择器的权重值为10,标签选择器的权重值为1

那么,很明显, (#idDiv + p) > (.classDiv + .classP),所以(#idDiv + p)生效了。

如果两个复杂选择器的权重值相同,那么写在后面的复杂选择器生效。

再比如:

1
2
3
4
5
6
7
div#idDiv p.classP{
background-color: red!important;
}

div .classDiv#idP{
background-color: green!important;
}

效果如下:

为什么呢?

在计算机的数学计算里,(无线大 + 1) > 无限大,这个跟数学计算不一样。

参考: