CSS 优先级计算
CSS 选择器优先级(Specificity)详解 · 难度:高级 · +15XP
CSS 选择器优先级(Specificity)详解
当多个 CSS 规则指向同一个元素时,浏览器通过优先级(Specificity)来决定应用哪条规则。理解优先级对于调试样式冲突至关重要。优先级可以看作是一个四位数(a, b, c, d)的权重系统。
优先级计算规则
选择器的优先级按以下规则计算(从高到低):
| 级别 | 选择器类型 | 示例 | 权重 |
|---|---|---|---|
| a | 内联样式 | style="color: red" | 1,0,0,0 |
| b | ID 选择器 | #header | 0,1,0,0 |
| c | 类/属性/伪类 | .nav, [type], :hover | 0,0,1,0 |
| d | 元素/伪元素 | div, p, ::before | 0,0,0,1 |
计算示例
/* 优先级: 0,0,0,1 */
p { color: black; }
/* 优先级: 0,0,1,0 */
.text { color: blue; }
/* 优先级: 0,1,0,0 */
#main { color: green; }
/* 优先级: 0,0,1,1 */
div.text { color: red; }
/* 优先级: 0,1,1,0 */
#main .text { color: purple; }
/* 优先级: 0,0,2,1 */
div.text.highlight { color: orange; }
/* 优先级: 0,1,1,1 */
#main div.text { color: cyan; }
!important 例外规则
!important 会覆盖所有常规优先级,但应尽量避免使用。当多个 !important 冲突时,按正常优先级决定。
p { color: red !important; }
#main p { color: blue; } /* 红色仍会生效,因为有 !important */
优先级实战问题
/* HTML: <div id="sidebar" class="widget">内容</div> */
#sidebar { background: blue; } /* 0,1,0,0 */
div.widget { background: red; } /* 0,0,1,1 */
/* 结果:蓝色(ID 选择器优先级更高) */
.widget { color: green; } /* 0,0,1,0 */
div { color: black; } /* 0,0,0,1 */
/* 结果:绿色(类选择器优先级更高) */
同等优先级时的处理
当优先级相同时,后定义的规则会覆盖先定义的规则(层叠规则)。
p { color: red; }
p { color: blue; } /* 这条生效(后面定义的) */
:is() 和 :where() 的影响
/* :is() 取其参数中优先级最高的 */
:is(#header, .nav, div) { } /* 优先级 = 0,1,0,0 */
/* :where() 的优先级始终为 0 */
:where(#header, .nav, div) { } /* 优先级 = 0,0,0,0 */
优先级速查表
| 选择器 | 优先级 (a,b,c,d) | 说明 |
|---|---|---|
| * | (0,0,0,0) | 通配符,无优先级 |
| p | (0,0,0,1) | 元素选择器 |
| .class | (0,0,1,0) | 类选择器 |
| #id | (0,1,0,0) | ID 选择器 |
| style="" | (1,0,0,0) | 内联样式(最高除 !important) |
| p.class | (0,0,1,1) | 元素 + 类 |
| .class1.class2 | (0,0,2,0) | 多重类选择器 |
???? 练习
- 写三个不同优先级的选择器指向同一个元素,观察哪个生效
- 创建一个样式冲突场景,用优先级计算解决
- 尝试使用 !important 并理解它的覆盖行为
- 比较 :is() 和 :where() 对优先级的影响
- 使用浏览器开发者工具查看元素最终的样式来源和优先级