什么是CSS选择器的优先级呢?
这里我先直接复制MDN的解释:
浏览器通过优先级来判断哪些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类选择器组成的匹配规则。
其实看这句话的时候我还不是很理解,所以我选择尝试着用代码来理解:
- HTML:
<div id="content" class="content">
颜色是什么
</div>
- CSS:
#contet{
color:green;
}
.content{
color:blue;
}
请问最后的文字颜色是什么呢?答案其实很简单,是红色。那么,为什么是红色呢?这就涉及到了优先级问题,同一块内容,我们同时用了ID选择器和类选择器,因为ID选择器的优先级大于类选择器,所以最终显示为红色。
那么,优先级到底是如何计算的呢?
通过MDN的学习,大致可以理解为:
内联>ID选择器>类选择器>标签选择器
它们是怎么计算的呢?通过查找资料,发现在《CSS REFACTORING》中有提到算法的过程,由于原版是英文,所以我直接找了中文的解释:
优先级是由 A 、B、C、D 的值来决定的,其中它们的值计算规则如下:
- 如果存在内联样式,那么
A = 1, 否则A = 0; B的值等于ID选择器出现的次数;C的值等于类选择器和属性选择器和伪类出现的总次数;D的值等于标签选择器和伪元素出现的总次数 。
这样一堆话看着好像还是很迷,那就再看个代码示例:
#nav-global > ul > li > a.nav-link
套用上面的算法,依次求出 A B C D 的值:
- 因为没有内联样式 ,所以
A = 0; - ID选择器总共出现了1次,
B = 1; - 类选择器出现了1次, 属性选择器出现了0次,伪类选择器出现0次,所以
C = (1 + 0 + 0) = 1; - 标签选择器出现了3次, 伪元素出现了0次,所以
D = (3 + 0) = 3;
上面算出的A 、 B、C、D 可以简记作:(0, 1, 1, 3)。
- html:
<div class="nav-list" id="nav-list">
<div class="item">nav1</div>
<div class="item">nav2</div>
</div>
复制代码
- CSS:
#nav-list .item {
color: #f00;
}
.nav-list .item {
color: #0f0;
}
复制代码
算出 #nav-list .item 的优先级是 (0, 1, 1, 0), .nav-list .item 的优先级是 (0, 0, 2, 0)。 左边第一位都是0, 再看看左边第二位,前者是1,后者是0, 所以(0, 1, 1, 0) 的大于 (0, 0, 2, 0) ,即 #nva-list .item 大于 .nav-list .item,所以字体会是红色。
优先级的特殊情况
但是,还有一个标签是例外的,就是!important。
当在一个样式声明中使用一个!important规则时,此声明将覆盖任何其他声明,包括可以覆盖内联样式。
所以,虽然一般谈及优先级的话不会把!important拍进去,但是它与最终的结果却有直接关系。
但是,尽管使用!important可以把优先级提到最高,方便后面加样式,但是MDN上面也解释了,使用!important是一个坏习惯,因为使用它时会破坏样式表中的固有的级联规则,使得调试找bug变得更加困难。
因此,MDN也给出了一些经验法则:
- 一定要优先考虑使用样式规则的优先级来解决问题而不是
!important。 - 只有在需要覆盖全站或外部CSS的特定页面中使用
!important。 - 永远不要在插件中使用
!important。 - 永远不要在全站范围的CSS代码中使用
!important。
好了,CSS优先级的学习先写到这里,之后有新的认识再来补充。