003-CSS选择器优先级

CSS 选择器优先级计算规则(详细解析)

CSS 选择器的优先级决定了当多条规则作用于同一个元素时,哪条规则会被应用。以下是完整的优先级计算机制:

一、优先级计算原理

优先级是通过 选择器权重值 来计算的,权重由 4 个级别组成(从左到右比较):

[内联样式, ID选择器, 类/属性/伪类选择器, 元素(标签)/伪元素选择器]

权重计算规则:

  1. 从高到低逐级比较,先比较内联样式,再比较ID,然后类,最后元素
  2. 高权重比较胜出后即停止,不再比较低级别
  3. 相同权重 时,后定义的样式覆盖先定义的

二、权重值详细分类

1. 内联样式(权重值:1,0,0,0)

1
<div style="color: red;"></div> <!-- 优先级最高 -->

2. ID 选择器(权重值:0,1,0,0)

1
#header { color: blue; }

3. 类/属性/伪类选择器(权重值:0,0,1,0)

  • 类选择器:.nav
  • 属性选择器:[type="text"]
  • 伪类选择器::hover, :nth-child()

4. 元素/伪元素选择器(权重值:0,0,0,1)

  • 元素选择器:div, p
  • 伪元素选择器:::before, ::after

5. 通配符/继承样式(权重值:0,0,0,0)

  • 通配符:*
  • 继承的样式(如从父元素继承的字体颜色)

三、计算示例

示例1:

1
2
3
4
5
6
7
8
9
#nav .list li a:hover { ... } /* 0,1,2,2 */
/* 分解:
#nav → 0,1,0,0
.list → 0,0,1,0
li → 0,0,0,1
a → 0,0,0,1
:hover → 0,0,1,0
合计:0,1,2,2
*/

示例2:

1
2
3
4
5
6
7
8
9
10
body .menu > ul li.active { ... } /* 0,0,2,3 */
/* 分解:
body → 0,0,0,1
.menu → 0,0,1,0
> → 不计算
ul → 0,0,0,1
li → 0,0,0,1
.active → 0,0,1,0
合计:0,0,2,3
*/

四、特殊规则

1. !important(最高优先级)

1
p { color: red !important; } /* 超越所有优先级 */
  • 会覆盖其他所有声明(包括内联样式)
  • 应该尽量避免使用,会导致样式难以维护

2. 相同权重时的顺序

1
2
.btn { color: blue; }  /* 规则1 */
.btn { color: green; } /* 规则2 - 最终生效 */

3. 组合选择器的计算

1
2
3
4
5
/* 权重:0,0,1,0 + 0,0,0,1 = 0,0,1,1 */
.nav li { ... }

/* 权重:0,0,1,0 + 0,0,1,0 = 0,0,2,0 */
.nav.active { ... }

4. :where() 和 :is() 的特殊性

1
2
:where(.nav) li { ... } /* 权重:0,0,0,1(:where()内的选择器不计权重) */
:is(.nav, #main) li { ... } /* 权重取参数中最高的(此处为0,1,0,1) */

五、优先级比较示例

选择器示例 权重值 说明
style="..." 1,0,0,0 内联样式
#header .logo 0,1,1,0 ID+类
ul#menu li.active 0,1,1,2 ID+类+2元素
.btn:hover 0,0,2,0 类+伪类
div p 0,0,0,2 2个元素
* 0,0,0,0 通配符

六、最佳实践建议

  1. 避免过度使用ID选择器 - 会导致优先级过高,难以覆盖
  2. 尽量使用类选择器 - 保持适度的优先级
  3. 避免!important - 除非必要(如覆盖第三方库样式)
  4. 使用CSS方法论(如BEM)来管理选择器复杂度
  5. 利用层叠特性 - 合理组织CSS顺序比提高优先级更好