CSS 选择器的权重(Specificity)决定了多个规则作用于同一元素时,哪条规则最终生效。权重计算有明确的规则,通常用一个“四元组” (a, b, c, d) 表示,从左到右优先级依次降低,左侧数值大的权重更高。以下是具体计算方法:
一、权重四元组的定义
四元组 (a, b, c, d) 中每个位置对应不同类型的选择器,数值越大,权重越高:
a:是否包含「内联样式」(style属性)。- 内联样式:
a = 1 - 非内联样式(外部/内部 CSS):
a = 0
- 内联样式:
b:「ID 选择器」的数量(每个 ID 加 1)。c:「类选择器、伪类、属性选择器」的数量(每个加 1)。- 类选择器:如
.class - 伪类:如
:hover、:nth-child() - 属性选择器:如
[type="text"]、[name="user"]
- 类选择器:如
d:「元素选择器、伪元素」的数量(每个加 1)。- 元素选择器:如
div、p - 伪元素:如
::before、::after
- 元素选择器:如
二、计算规则
- 分别统计选择器中上述四类选择器的数量,填充到四元组
(a, b, c, d)中。 - 比较权重时,从左到右依次比较数值:
- 若
a不同,a大的权重更高; - 若
a相同,比较b,以此类推; - 只有前一项数值相等时,才比较后一项。
- 若
- 通配符(
*)、组合符(+、>、~、空格)不影响权重,不计入任何位置。
三、实例计算
通过具体例子理解如何计算:
| 选择器 | 内联样式(a) | ID选择器(b) | 类/伪类/属性(c) | 元素/伪元素(d) | 权重四元组 |
|---|---|---|---|---|---|
div |
0 | 0 | 0 | 1(元素) | (0, 0, 0, 1) |
.box |
0 | 0 | 1(类) | 0 | (0, 0, 1, 0) |
#header |
0 | 1(ID) | 0 | 0 | (0, 1, 0, 0) |
div p |
0 | 0 | 0 | 2(两个元素) | (0, 0, 0, 2) |
.list li:hover |
0 | 0 | 1(类)+1(伪类)=2 | 1(元素) | (0, 0, 2, 1) |
#nav .item[data-id="1"] |
0 | 1(ID) | 1(类)+1(属性)=2 | 0 | (0, 1, 2, 0) |
div#main .content::before |
0 | 1(ID) | 1(类) | 1(元素)+1(伪元素)=2 | (0, 1, 1, 2) |
<div style="color: red"> |
1(内联) | 0 | 0 | 0 | (1, 0, 0, 0) |
四、权重比较示例
(0, 1, 0, 0)(#header) >(0, 0, 3, 2)(.a .b .c div p)
原因:b位置前者为 1,后者为 0,左侧数值更大,无需比较后续。(0, 0, 2, 1)(.list li:hover) >(0, 0, 1, 3)(.item div span a)
原因:c位置前者为 2,后者为 1,前者权重更高。(0, 1, 2, 0)(#nav .item[data-id]) >(0, 1, 1, 5)(#nav .box div p span a)
原因:a和b相同,比较c位置(2 > 1)。
五、特殊情况
!important优先级最高
任何带有!important的样式会覆盖其他所有规则(包括内联样式),例如:.box { color: red !important; } /* 优先级最高 */⚠️ 注意:尽量避免滥用
!important,否则会导致样式难以维护。相同权重时,“后定义的规则生效”
若两个选择器权重完全相同,CSS 代码中后出现的规则会覆盖先出现的规则:.box { color: blue; } /* 先定义 */ .box { color: green; } /* 后定义,最终生效 */继承的样式权重最低
元素从父元素继承的样式,会被元素自身的任何样式(无论权重多低)覆盖:.parent { color: red; } /* 父元素样式,子元素继承 */ .child { color: blue; } /* 子元素自身样式,权重 (0,0,1,0),覆盖继承 */
总结
计算选择器权重的核心是按“内联样式 > ID > 类/伪类/属性 > 元素/伪元素”的顺序统计数量,形成四元组后从左到右比较。浏览器开发者工具的「Styles」面板会自动按权重排序规则,划掉被覆盖的样式,可辅助验证计算结果。掌握权重计算,能有效解决样式冲突问题。