CSS 权重的计算规则

1. CSS 权重的计算规则

CSS 权重由四个部分组成,格式为 (a, b, c, d)​:

  • a​: 内联样式(style="..."​)的数量。
  • b​: ID 选择器的数量。
  • c​: 类选择器、属性选择器、伪类选择器的数量。
  • d​: 元素选择器、伪元素选择器的数量。

每个部分的权重值是累加的,优先级从左到右依次递减。


2. 分析选择器

比如 #layouts div.layout__center div.protyle-content:not([data-fullwidth="true"]) div.protyle-wysiwyg

分解选择器

#layouts div.layout__center div.protyle-content:not([data-fullwidth="true"]) div.protyle-wysiwyg

逐部分分析

  1. **ID 选择器 (**​ #layouts)

    • 匹配一个 ID 选择器:#layouts​。
    • 权重贡献:b = 1​。
  2. 类选择器和伪类选择器

    • .layout__center​:类选择器。
    • .protyle-content​:类选择器。
    • :not([data-fullwidth="true"])​:伪类选择器。
    • 权重贡献:c = 3​(2 个类选择器 + 1 个伪类选择器)。
  3. 元素选择器

    • div​(出现 3 次):div.layout__center​、div.protyle-content​、div.protyle-wysiwyg​。
    • 权重贡献:d = 3​。

总结

  • a​(内联样式):0(没有内联样式)。
  • b​(ID 选择器):1(#layouts​)。
  • c​(类选择器、属性选择器、伪类选择器):4(.layout__center​、.protyle-content​、:not([data-fullwidth="true"]​)。
  • d​(元素选择器):3(div​ 出现 3 次)。

因此,最终的权重为:(0, 1, 4, 3)​。


3. 权重表示法

在某些工具中,权重可能会以简化的形式表示,例如:

  • (1, 4, 3)​ 表示 (0, 1, 4, 3)​。
  • 工具可能省略了第一个 0​,因为内联样式通常不参与此类选择器。

4. 权重比较

如果需要与其他选择器比较优先级,可以按照以下规则:

  1. 比较 a​(内联样式)。
  2. 如果 a​ 相同,比较 b​(ID 选择器)。
  3. 如果 b​ 相同,比较 c​(类选择器、属性选择器、伪类选择器)。
  4. 如果 c​ 相同,比较 d​(元素选择器)。

例如:

  • (0, 1, 4, 3)​ > (0, 0, 5, 10)​(因为 b​ 更高)。
  • (0, 1, 4, 3)​ < (0, 2, 0, 0)​(因为 b​ 更低)。

5. 工具验证

使用工具(如 Specificity CalculatorCss Specificity Calculator或其他在线工具)可以验证该选择器的权重为 (1, 4, 3)​,这与手动计算的结果一致。


6. 总结

选择器 #layouts div.layout__center div.protyle-content:not([data-fullwidth="true"]) div.protyle-wysiwyg​ 的 CSS 权重为 (0, 1, 4, 3)​,工具显示为 (1, 4, 3)​ 是合理的,因为它省略了第一个 0​。


如果两个选择器的权重计算结果都是 (0, 1, 4, 3)​(或简化为 143​),那么它们的优先级是相同的。在这种情况下,CSS 的 层叠规则(Cascading Rules)会决定哪个样式最终生效。

以下是 CSS 层叠规则的详细说明:

1. 如果权重相同,优先级如何决定?

当两个选择器的权重相同时,CSS 按照以下顺序决定优先级:

(1) 后声明的样式优先

  • 在同一个样式表中,后声明的规则会覆盖先前的规则。

  • 示例:

    .example {
        color: red; /* 这个会被覆盖 */
    }
    .example {
        color: blue; /* 这个生效 */
    }
    

    最终颜色为蓝色,因为它是后声明的。

(2) 外部样式表 vs 内部样式表

  • 如果样式来自不同的来源,优先级顺序如下:

    1. 用户代理样式(浏览器默认样式)。
    2. 外部样式表(如 <link>​ 引入的样式文件)。
    3. 内部样式表(如 <style>​ 标签中的样式)。
    4. 内联样式(如 style="..."​)。

(3) 使用 !important

  • 如果某个样式规则使用了 !important​,它会覆盖所有未使用 !important​ 的规则,无论权重如何。

  • 示例:

    .example {
        color: red !important; /* 这个生效 */
    }
    .example {
        color: blue;
    }
    

    最终颜色为红色,因为 !important​ 提升了优先级。


2. 实际案例分析

假设你有两个权重均为 (0, 1, 4, 3)​ 的选择器:

选择器 A

#layouts div.layout__center div.protyle-content:not([data-fullwidth="true"]) div.protyle-wysiwyg {
    color: red;
}

选择器 B

#layouts div.layout__center div.protyle-content:not([data-fullwidth="true"]) div.protyle-wysiwyg {
    color: blue;
}

优先级判定

  1. 权重相同:两个选择器的权重都是 (0, 1, 4, 3)​。

  2. 后声明优先:如果选择器 B 在样式表中出现在选择器 A 之后,则 B 的样式会覆盖 A 的样式。

    • 最终颜色为蓝色。

特殊情况

如果其中一个选择器使用了 !important​,例如:

#layouts div.layout__center div.protyle-content:not([data-fullwidth="true"]) div.protyle-wysiwyg {
    color: red !important;
}

即使选择器 A 出现在前面,由于 !important​ 的存在,最终颜色仍为红色。


3. 总结

当两个选择器的权重相同时:

  1. 后声明的样式优先
  2. 如果一个样式使用了 !important​,它会覆盖其他未使用 !important​ 的样式。
  3. 如果仍然无法区分优先级,可以检查样式来源(如外部样式表、内部样式表等)。
image.png

留下你的脚步
推荐阅读