这是我参与「第四届青训营」笔记创作活动的第1天。
一个没有计算机基础的同学入门前端, 也可以在第一天写出一个样式不错的静态网页。但是,大部分人,包括我,其实并不清楚浏览器是如何通过CSS确定最终的网页样式的。在上了《深入CSS》这届课之后,我的很多问题都得到了解答。
当多个选择器匹配到同一个元素时,如何确定元素的样式? 下面我对CSS选择器的优先级规则做一个总结。
选择器的特异度(Specificity)
每一个选择器都有相应的权重,权重为一个三维向量,初始值 0-0-0。一个选择器根据如下规则决定最终权重:
- 每出现一个 id选择器, 权重增加 1-0-0
- 每出现一个 class选择器,attribute选择器,pseudo-class选择器,权重增加 0-1-0
- 每出现一个 type选择器,pseudo-element选择器,权重增加 0-0-1
- 通配选择符 * , 关系选择符 >, +, ~等,伪类
:is(), :not()与:where()不增加权重
考虑如下的HTML代码片段
<div class="container" id="box1">
<div class="card" id="box2">
<h1 id="title">Hello world</h1>
<a href="https://juejin.cn/">前往掘金</a>
</div>
</div>
根据上述规则,我们可以计算各个选择器的权重
#box2 .title的权重为 1-1-0a:hover的权重为 0-1-1.card::before的权重为 0-1-1
权重高低的比较方法为依次比较权重的各个分量,比如 1-0-0 高于 0-5-8, 2-3-0 高于 2-2-4。当多个选择器定义的样式产生冲突时, 选择权重最高的选择器。
若多个权重相同的选择器匹配到了同一个元素,则遵循"后来者优先"规则,选取CSS文件中最后出现的选择器对应的样式。
特殊规则
1. :is(), :not(), :where()伪类选择器
- 虽然以上三个伪类选择器本身不会增加权重, 但是其内部声明的选择器会影响其权重
- 在
:where()里出现的选择器也不会增加权重 - 在
:is(), :not()内部声明的各组选择器中,选择权重最高的一组作为其权重
我们还是通过几个例子加深印象
:where(#container) h1的权重为 0-0-1:is(#box1, .card) h1的权重为1-0-1
2. 内联样式
在HTML文件中直接定义的style会覆盖CSS文件中的style. 例如
<h1 id="title" style="color:blue;">Hello world</h1>
#title {
color: red;
}
在开发者工具查看样式
3. !important
如果想要在CSS中覆盖内联样式,就需要在样式里加上 !important字样,比如
注: 在HTML文件直接定义样式,以及用!important关键字都不是一个好的实践,应该尽量避免.
总结
- 样式中有
!important,则优先考虑带有!important的样式, 若有多个带有!important的样式,则这些样式之间继续按照下列规则比较优先级 - 在HTML文件中直接定义的内联样式优先级高于CSS文件中定义的样式
- 在CSS文件中,采用权重最高的选择器定义的样式
- 若多个选择器都是最高权重,则选择这些选择器中最后出现的选择器的样式
参考资料
MDN:Specificity developer.mozilla.org/en-US/docs/…