CSS 权重

kaichikaichi • 2022-02-18

4 分钟0 阅读

你的样式应用到你选择的元素上,很好,完美工作。但是如果一个元素上有多条规则,那么浏览器该如何决定应用谁,覆盖谁呢?首先能想到的就是后面的覆盖前面的,但是如果有 !important 或者内联样式 style="" 呢?它们又处于什么位置上呢?

很显然,根据位置信息无法处理上面的情况。浏览器是通过优先级来判断哪些属性与一个元素最为相关,从而应用这些属性值。

如何计算优先级?

每个 CSS 声明的权重取决于匹配的选择器中每一个选择器的类型决定。例如:

<div id="test">
  <span>hello</span>
</div>
div#test span {
  color: red;
}

div span {
  color: green;
}

span {
  color: blue;
}

最后文本是红色(虽然蓝色写在最后),先不考虑选择器类型,div#test span 选择器明显比后面两个多了某些选择器,所以提高了优先级。

如果多个 CSS 声明具有相同的优先级时,后面的则会覆盖前面的。

选择器类型

CSS 的选择器类型在计算权重时可分为下面几类。

类型例子权重影响
元素选择器/伪元素选择器h1,::before...0-0-Z
类选择器/伪类选择器/属性选择器.test,:hover,[type="radio"]...0-Y-0
ID 选择器#testX-0-0

:not() 伪类选择器对优先级没有影响,但是传入的选择器参数会影响优先级。

通配符选择器(*)和关系选择符(+, >, ~, _, ||)对优先级没有影响。

权重表示

既然需要知道权重,那么这个分数如何表示?上面介绍影响权重的选择器类型时列出了其权重影响,我们可以以 X-Y-Z 形式来表示,从左到右权重由高到低。

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

上面这个选择器的权重是 0-4-1

  • 4:类选择器 .my-class.another-class,属性选择器 [href],伪类选择器 :hover
  • 1:元素选择器 a

不进位,即使 Z 得分 10000,优先级也不会大于一个 Y 得分。官大一级压死人。

基于形式,a#my-ida[id="my-id"] 权重分别为 1-0-10-1-1

比较

从高到低依次比较,1-0-0 > 0-10-1

内联样式

那么内联样式具有什么优先级呢?之前的权重表示有三位,内联样式则是更高一个优先级(再加一位)。

<!-- 权重:1-0-0-0 -->
<a style="color: red">link</a>

!important 规则

!important 规则虽然和优先级无关,但是和最终结果相关,!important 会覆盖掉任何其它 CSS 声明,即使是内联样式。可以覆盖 !important 值的唯一方法就是在其后面声明另一个拥有相同或更大权重的 important 规则。可以这样认为,!important 规则的权重是 1-0-0-0-0

不要遇到样式被覆盖的问题就添加 !important 规则,优先考虑使用样式规则优先级解决。

文档结构无关

<html>
  <body>
    <h1>Here is a title!</h1>
  </body>
</html>
body h1 {
  color: green;
}

html h1 {
  color: purple;
}

不会因为 body h1 更近而拥有更高优先级。

直接添加样式 vs. 继承样式

<html>
  <body id="parent">
    <h1>Here is a title!</h1>
  </body>
</html>
#parent {
  color: green;
}

h1 {
  color: purple;
}

为目标直接添加样式永远比继承样式优先级高,无视优先级的遗传规则。

在 Github 上编辑