在开发过程中,我们常常会遇到"为什么我的样式没生效?"、"为什么另一个样式把它覆盖了?"等问题。这些问题的背后,其实都涉及到一个非常核心的知识点 ------ CSS 选择器的优先级。
本文将系统讲解 CSS 常见选择器的类型、权重计算方式以及优先级规则,帮助你从根源上理解浏览器是如何决定使用哪一条样式的。
🧩 一、CSS 选择器分类及权重说明
选择器类型 | 示例写法 | 权重值 |
---|---|---|
内联样式(style) | <div style="color: red"> |
1000 |
ID 选择器 | #header |
100 |
类选择器 / 属性选择器 / 伪类选择器 | .btn , [type="text"] , :hover |
10 |
标签选择器 / 伪元素选择器 | div , ::before |
1 |
通配符选择器 / 子选择器 / 后代选择器 / 相邻兄弟选择器 | * , ul > li , li a , h1 + p |
0 |
⚠️ 注意:权重是按位相加,不是简单的数值比较!
🔢 二、如何计算选择器优先级?
CSS 通过以下四个层级来计算优先级:
- 行内样式(inline):1000
- ID 选择器数量:100 × n
- 类选择器、属性选择器、伪类选择器数量:10 × n
- 标签选择器、伪元素选择器数量:1 × n
✅ 示例解析:
css
/* 权重 = 100 (id) */
#main-content {
color: red;
}
/* 权重 = 20 (两个类) */
.sidebar .highlight {
color: blue;
}
/* 权重 = 11 (1个类 + 1个标签) */
div.content {
color: green;
}
如果三个选择器都作用于同一个元素,最终生效的是 #main-content
,因为它的权重最高。
📌 三、优先级判断原则总结
判断维度 | 描述 |
---|---|
!important | 最高优先级,直接跳过其他所有规则(慎用) |
权重比较 | 按照上面的权重规则进行比较,谁大谁生效 |
同权重下顺序 | 如果多个选择器权重相同,则后写的样式覆盖先写的样式 |
继承样式 | 权重最低,容易被覆盖,常用于字体、颜色等属性 |
样式来源优先级 | 内联 > 内部样式表 > 外部样式表 > 用户样式 > 浏览器默认样式 |
💡 四、常见问题与注意事项
1. !important 的使用建议
- 虽然它可以强行提升某条样式的优先级,但应避免滥用;
- 推荐场景:临时调试、第三方库样式覆盖;
- 不推荐场景:日常开发中频繁使用,会导致后期难以维护;
css
.red {
color: red !important;
}
2. 后代选择器 vs 子选择器
div span
是后代选择器(权值 0),匹配 div 下所有 span;div > span
是子选择器(权值 0),只匹配 div 的直接子元素 span;- 它们的优先级一样,靠顺序决定是否生效;
3. 继承样式的优先级最低
- 如
font-size
,color
,font-family
等属性可以从父元素继承下来; - 一旦有本地定义的样式,就会覆盖继承来的样式;
🧪 五、真实开发中的优先级陷阱
❗ 误区一:.class1 .class2
和 .class3
哪个优先级更高?
css
.class1 .class2 {
color: red; /* 权重:10 + 10 = 20 */
}
.class3 {
color: blue; /* 权重:10 */
}
👉 .class1 .class2
更高,所以会生效红色。
❗ 误区二:#id
和 body #id
哪个更强?
css
#nav {
color: red; /* 权重:100 */
}
body #nav {
color: blue; /* 权重:100 + 1 = 101 */
}
👉 后者更强,蓝色生效。
📈 六、优化建议与最佳实践
实践 | 说明 |
---|---|
✅ 避免过度使用 ID 选择器 | 虽然好用,但复用性差且权重过高,不利于组件化开发 |
✅ 少用 !important |
可读性和可维护性差,易造成样式混乱 |
✅ 使用 BEM 或 CSS Modules 等命名规范 | 提升类名可读性,减少冲突 |
✅ 合理使用层叠顺序 | 控制样式优先级,避免不必要的嵌套和复杂选择器 |
✅ 使用开发者工具查看最终样式 | Chrome DevTools 中可以清晰看到哪条样式生效了 |
📌 七、总结表格:快速查阅优先级
选择器类型 | 示例 | 权重 |
---|---|---|
行内样式 | style="color:red" |
1000 |
ID 选择器 | #header |
100 |
类选择器 / 伪类 / 属性 | .btn , :hover , [type] |
10 |
标签选择器 / 伪元素 | div , ::after |
1 |
后代 / 子 / 相邻 / 通配 | div a , > , + , * |
0 |