CSS 优先级 (Specificity)
CSS 优先级是一个非常重要的概念。当多个 CSS 规则都应用于同一个元素时,浏览器需要一种方法来决定哪个规则最终生效。这个决策过程就是基于优先级 (Specificity) 的。
优先级可以被看作是一个选择器的“权重”或“分数”。权重越高的选择器,其样式就越有可能被应用。
优先级的计算规则
浏览器通过计算一个选择器的四个部分来确定其优先级,可以表示为 (a, b, c, d):
- a (行内样式): 如果样式是写在 HTML 元素的
style属性中(行内样式),则 a=1,否则 a=0。 - b (ID 选择器): 计算选择器中 ID 选择器 (
#id) 的数量。 - c (类、属性和伪类选择器): 计算选择器中类选择器 (
.class)、属性选择器 ([type="text"]) 和伪类 (:hover) 的数量。 - d (元素和伪元素选择器): 计算选择器中元素选择器 (
div) 和伪元素 (::before) 的数量。
比较规则: 从左到右依次比较 a, b, c, d 的值。第一个不为零的、值更大的选择器获胜。例如,(0, 1, 0, 0) 的优先级高于 (0, 0, 10, 0),因为 b 的值 1 大于 0,后面的值就不再比较了。
示例
| 选择器 | 计算 (a, b, c, d) | 优先级 | 解释 |
|---|---|---|---|
p | (0, 0, 0, 1) | 1 | 1 个元素选择器 |
p.red | (0, 0, 1, 1) | 11 | 1 个类选择器, 1 个元素选择器 |
#my-id | (0, 1, 0, 0) | 100 | 1 个 ID 选择器 |
div#my-id | (0, 1, 0, 1) | 101 | 1 个 ID, 1 个元素选择器 |
a:hover | (0, 0, 1, 1) | 11 | 1 个伪类, 1 个元素选择器 |
ul li a.active | (0, 0, 1, 3) | 13 | 1 个类, 3 个元素选择器 |
[type="button"] | (0, 0, 1, 0) | 10 | 1 个属性选择器 |
style="..." | (1, 0, 0, 0) | 1000 | 行内样式 |
特殊规则
1. !important
在一个样式声明的末尾添加 !important 会使其覆盖任何其他声明,无论其优先级如何。!important 会破坏正常的层叠规则,应尽量避免使用。 它通常只在需要覆盖第三方库或内联样式等特殊情况下才被考虑。
css
p {
color: blue !important;
}
p#my-id {
color: red; /* 这个规则不会生效 */
}2. 通用选择器和组合选择器
- 通用选择器 (
*) 的优先级为 0(0, 0, 0, 0)。 - 组合选择器 (
+,>,~,) 本身不增加优先级。
3. :not() 伪类
:not() 伪类本身不增加优先级,但其括号内的选择器会正常计算优先级。
解决优先级冲突
- 提高选择器的特异性: 最直接的方法是创建一个比现有规则更具体的选择器。例如,用
div.my-class代替.my-class。 - 利用源码顺序: 如果两个选择器的优先级完全相同,那么在样式表中后出现的规则会获胜。
- 避免使用
!important: 除非万不得已。 - 使用 class: 尽量使用 class 来定义样式,避免使用 ID 进行样式化,因为 ID 的优先级非常高,难以覆盖。
理解优先级是调试 CSS 问题的关键技能。当你发现某个样式没有按预期工作时,首先应该检查的就是是否有其他更高优先级的规则覆盖了它。