CSS选择器优先级与权重计算
当多条规则应用于同一元素时,优先级决定最终生效的样式。
优先级计算规则
权重值系统
| 选择器类型 | 权重值 | 示例 |
|---|---|---|
| 内联样式 | 1,0,0,0 | style="..." |
| ID选择器 | 0,1,0,0 | #id |
| 类选择器 | 0,0,1,0 | .class |
| 属性选择器 | 0,0,1,0 | [attr] |
| 伪类选择器 | 0,0,1,0 | :hover |
| 元素选择器 | 0,0,0,1 | div |
| 伪元素选择器 | 0,0,0,1 | ::before |
| 通配选择器 | 0,0,0,0 | * |
计算方法
将选择器中各类型数量相加:
CSS
/* 示例1 */
#header .nav li a:hover {
/* 1个ID + 1个类 + 2个元素 + 1个伪类 */
/* 权重: 0,1,2,2 */
}
/* 示例2 */
.container .item.active {
/* 0个ID + 3个类 */
/* 权重: 0,0,3,0 */
}
/* 示例3 */
div p span {
/* 3个元素 */
/* 权重: 0,0,0,3 */
}
权重比较规则
从左到右比较
CSS
/* 比较: 0,1,0,0 vs 0,0,10,0 */
#id { } /* 权重: 0,1,0,0 */
.class1.class2.class3.class4.class5.class6.class7.class8.class9.class10 { }
/* 权重: 0,0,10,0 */
/* 结果: #id胜出 */
/* ID权重(第2位) > 类权重(第3位) */
同权重后声明胜出
CSS
.button {
color: blue; /* 先声明 */
}
.btn {
color: red; /* 后声明,同权重0,0,1,0 */
}
/* 结果: color: red生效 */
内联样式优先级
最高权重
CSS
/* CSS规则 */
#header {
color: blue; /* 权重: 0,1,0,0 */
}
/* 内联样式 */
<div id="header" style="color: red;">
<!-- 权重: 1,0,0,0,优先级更高 -->
<!-- 最终颜色: red -->
</div>
覆盖内联样式
只有!important能覆盖内联样式:
CSS
#header {
color: blue !important; /* 覆盖内联 */
}
组合选择器权重
后代选择器
CSS
#nav .item a {
/* 权重: 0,1,1,1 */
/* 1个ID + 1个类 + 1个元素 */
}
子代选择器
CSS
#nav > .item > a {
/* 权重: 0,1,1,1 */
/* 与后代选择器权重计算相同 */
}
多ID选择器
CSS
#header #nav .item {
/* 权重: 0,2,1,0 */
/* 2个ID + 1个类 */
}
特殊选择器权重
通配选择器权重为0
CSS
* {
margin: 0; /* 权重: 0,0,0,0 */
}
div {
margin: 10px; /* 权重: 0,0,0,1 */
}
/* div胜出,margin: 10px生效 */
组合选择器不累加
CSS
:is(.class1, .class2) {
/* :is()取参数中最高权重 */
/* 权重: 0,0,1,0 */
}
:where(.class1, .class2) {
/* :where()权重始终为0 */
/* 权重: 0,0,0,0 */
}
:not()权重
CSS
:not(.class) {
/* :not()本身不增加权重 */
/* 权重等于参数权重: 0,0,1,0 */
}
div:not(.active) {
/* 元素 + 类 = 0,0,1,1 */
}
实际案例分析
案例1:样式冲突
CSS
/* 规则A */
#sidebar .widget h3 {
color: blue; /* 权重: 0,1,1,1 */
}
/* 规则B */
.widget h3.title {
color: red; /* 权重: 0,0,2,1 */
}
/* 结果: 规则A胜出,color: blue */
案例2:相同权重
CSS
/* 规则A */
.card .title {
font-size: 16px; /* 权重: 0,0,2,0,先声明 */
}
/* 规则B */
.box .heading {
font-size: 18px; /* 权重: 0,0,2,0,后声明 */
}
/* 若元素同时有两个类,后声明生效 */
案例3:内联vsID
CSS
#unique {
background: blue; /* 权重: 0,1,0,0 */
}
<div id="unique" style="background: red;">
<!-- 内联权重: 1,0,0,0 -->
<!-- 最终: background: red -->
</div>
优先级调试技巧
查看计算权重
JavaScript
// DevTools查看
// Elements面板 → 选中元素 → Styles面板
// 显示每个规则的权重来源
检查生效规则
CSS
DevTools → Elements → Styles
- 生效规则:无删除线
- 未生效规则:有删除线
- 显示优先级更低的原因
最佳实践
避免过度使用ID
CSS
/* 不推荐 */
#header #nav #menu .item a {
color: blue; /* 权重过高,难以覆盖 */
}
/* 推荐 */
.header-nav .menu-item-link {
color: blue; /* 权重适中 */
}
保持权重平衡
CSS
/* 不推荐:权重混乱 */
.btn { } /* 0,0,1,0 */
#submit-btn { } /* 0,1,0,0 */
button.submit { }/* 0,0,1,1 */
/* 推荐:统一层级 */
.btn { }
.btn-primary { }
.btn-large { }
使用BEM命名控制权重
text
/* BEM风格,权重一致 */
.card { } /* 0,0,1,0 */
.card__title { } /* 0,0,1,0 */
.card--featured { } /* 0,0,1,0 */
权重计算总结表
| 选择器 | 权重 | 计算说明 |
|---|---|---|
style="" | 1,0,0,0 | 内联最高 |
#id | 0,1,0,0 | ID选择器 |
.class | 0,0,1,0 | 类选择器 |
[attr] | 0,0,1,0 | 属性选择器 |
:hover | 0,0,1,0 | 伪类 |
div | 0,0,0,1 | 元素选择器 |
::before | 0,0,0,1 | 伪元素 |
* | 0,0,0,0 | 通配选择器 |
+ > ~ | 不影响 | 组合符不增加权重 |
要点总结
- 权重格式:(内联, ID, 类/属性/伪类, 元素/伪元素)
- 从左到右逐位比较,高位胜出
- 同权重时后声明胜出
- 内联样式权重最高(1,0,0,0)
!important可覆盖任何权重- 避免过度使用ID导致权重过高
- 使用BEM保持权重平衡
📝 发现内容有误?点击此处直接编辑