复习笔记-CSS选择器优先级

201 阅读3分钟

什么是CSS选择器的优先级呢?

这里我先直接复制MDN的解释:

浏览器通过优先级来判断哪些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类选择器组成的匹配规则。

其实看这句话的时候我还不是很理解,所以我选择尝试着用代码来理解:

  • HTML:
    <div id="content" class="content">
        颜色是什么
    </div>
  • CSS:
#contet{
    color:green;
}
.content{
    color:blue;
}

请问最后的文字颜色是什么呢?答案其实很简单,是红色。那么,为什么是红色呢?这就涉及到了优先级问题,同一块内容,我们同时用了ID选择器类选择器,因为ID选择器的优先级大于类选择器,所以最终显示为红色。

那么,优先级到底是如何计算的呢?

通过MDN的学习,大致可以理解为:

内联>ID选择器>类选择器>标签选择器

它们是怎么计算的呢?通过查找资料,发现在《CSS REFACTORING》中有提到算法的过程,由于原版是英文,所以我直接找了中文的解释:

优先级是由 ABCD 的值来决定的,其中它们的值计算规则如下:

  1. 如果存在内联样式,那么 A = 1, 否则 A = 0;
  2. B 的值等于 ID选择器 出现的次数;
  3. C 的值等于 类选择器属性选择器伪类 出现的总次数;
  4. D 的值等于 标签选择器伪元素 出现的总次数 。

这样一堆话看着好像还是很迷,那就再看个代码示例:

#nav-global > ul > li > a.nav-link

套用上面的算法,依次求出 A B C D 的值:

  1. 因为没有内联样式 ,所以 A = 0;
  2. ID选择器总共出现了1次, B = 1;
  3. 类选择器出现了1次, 属性选择器出现了0次,伪类选择器出现0次,所以 C = (1 + 0 + 0) = 1
  4. 标签选择器出现了3次, 伪元素出现了0次,所以 D = (3 + 0) = 3;

上面算出的ABCD 可以简记作:(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优先级的学习先写到这里,之后有新的认识再来补充。

优先级 - CSS(层叠样式表) | MDN (mozilla.org)