在 CSS 中,当多个选择器同时作用于同一个元素时,浏览器会根据一套明确的规则来决定最终应用哪个样式,这套规则就是CSS选择器的优先级。
优先级的核心判定规则
CSS 优先级的计算通常采用四位数 (a, b, c, d) 的权重规则,从左到右依次比较,高位胜出。如果权重完全相同,则遵循“后来居上” 原则,即写在 CSS 后面的样式会覆盖前面的。
具体的权重分配如下:
- 第一顺位:
!important它不属于常规权重计算,但拥有最高话语权,可以强制覆盖页面上的任何普通样式(包括内联样式)。 - 第二顺位:内联样式(a = 1)
直接写在 HTML 标签
style属性里的样式,例如<div style="color: red;"></div>,权重记为1, 0, 0, 0。 - 第三顺位:ID 选择器(b = 1)
例如
#header,每出现一个 ID 选择器,权重加0, 1, 0, 0。 - 第四顺位:类、属性、伪类选择器(c = 1)
- 类选择器:例如
.box - 属性选择器:例如
[type="text"] - 伪类选择器:例如
:hover、:focus、:nth-child(n)每出现一个,权重加0, 0, 1, 0。
- 类选择器:例如
- 第五顺位:标签、伪元素选择器(d = 1)
- 标签选择器:例如
div、p、span - 伪元素选择器:例如
::before、::after、::first-line每出现一个,权重加0, 0, 0, 1。
- 标签选择器:例如
- 零权重:通配符与关系符
通配符
*以及关系符(如>、+、~、空格)的权重为0, 0, 0, 0,不参与优先级的计算。
权重计算示例
为了方便理解,我们可以看几个具体的权重对比:
| 选择器示例 | 权重计算 (a, b, c, d) | 说明 |
|---|---|---|
* | 0, 0, 0, 0 | 通配符,权重最低 |
div p | 0, 0, 0, 2 | 2个标签选择器 |
.box p | 0, 0, 1, 1 | 1个类 + 1个标签 |
#nav .item:hover | 0, 1, 2, 0 | 1个ID + 1个类 + 1个伪类 |
<div style="..."> | 1, 0, 0, 0 | 内联样式 |
特别注意与高频考点
- 权重不会进位:CSS 的权重是按位比较的,而不是简单的数学相加。即使你写了 256 个标签选择器(0, 0, 0, 256),它的优先级依然低于 1 个类选择器(0, 0, 1, 0)。
- 继承的样式权重最低:通过父元素继承而来的样式,其优先级低于任何直接作用于该元素的选择器(哪怕是一个权重为 0 的通配符选择器)。
- 慎用
!important:虽然它能解决燃眉之急,但会破坏 CSS 天然的级联规则,导致后期代码极难维护和调试。 - 新特性补充:在现代 CSS 中,
:not()伪类本身不增加权重,但其括号内部的选择器会参与计算;而:where()的权重永远为 0,非常适合用来编写零权重的基础样式库。