当多个 CSS 规则应用于同一个元素时,浏览器需要决定使用哪个规则。这就是 CSS 优先级(也称为权重或特异性)的作用。理解 CSS 优先级对于编写可维护、可预测的 CSS 样式至关重要。
CSS 优先级是一个用于确定哪个样式规则应该被应用的机制。当多个规则选择同一个元素时,浏览器会根据优先级规则来决定最终应用的样式。
/* 规则 1 */
p {
color: blue;
}
/* 规则 2 */
.text {
color: green;
}
/* 规则 3 */
#content {
color: red;
}
/* 应用于这个元素 */
<p id="content" class="text">这段文字是什么颜色?</p>
/* 结果:红色 - 因为 ID 选择器的优先级最高 */
CSS 优先级用一个三元组表示:(ID 选择器数量, 类选择器数量, 元素选择器数量)。
/* 通配符选择器 */
* { /* 优先级:(0,0,0) */ }
/* 元素选择器 */
p { /* 优先级:(0,0,1) */ }
div { /* 优先级:(0,0,1) */ }
/* 类选择器 */
.text { /* 优先级:(0,1,0) */ }
.highlight { /* 优先级:(0,1,0) */ }
/* ID 选择器 */
#header { /* 优先级:(1,0,0) */ }
#content { /* 优先级:(1,0,0) */ }
/* 优先级:(0,0,1) */
p {
color: blue;
}
/* 优先级:(0,1,0) */
.text {
color: green;
}
/* 优先级:(1,0,0) */
#content {
color: red;
}
/* 优先级:(0,0,2) */
div p {
color: purple;
}
/* 优先级:(0,1,1) */
div .text {
color: orange;
}
/* 优先级:(1,0,1) */
#content p {
color: pink;
}
/* 优先级:(1,1,0) */
#content .text {
color: brown;
}
当比较两个选择器的优先级时,从左到右依次比较三元组的值:
/* 规则 A:优先级 (1,0,0) */
#header {
color: red;
}
/* 规则 B:优先级 (0,10,10) */
.nav .menu .item .link .text {
color: blue;
}
/* 比较过程:
* 第一位:1 > 0,所以规则 A 优先级更高
* 结果:红色
*/
/* 规则 C:优先级 (0,2,0) */
.text.highlight {
color: green;
}
/* 规则 D:优先级 (0,1,5) */
div ul li a span em strong {
color: yellow;
}
/* 比较过程:
* 第一位:0 = 0,继续比较
* 第二位:2 > 1,所以规则 C 优先级更高
* 结果:绿色
*/
组合选择器的优先级是所有选择器优先级的总和:
/* 后代选择器 */
div p {
/* 优先级:(0,0,2) = (0,0,1) + (0,0,1) */
color: blue;
}
/* 子元素选择器 */
div > p {
/* 优先级:(0,0,2) = (0,0,1) + (0,0,1) */
color: green;
}
/* 类选择器 + 元素选择器 */
.text p {
/* 优先级:(0,1,1) = (0,1,0) + (0,0,1) */
color: red;
}
/* ID 选择器 + 类选择器 */
#header .logo {
/* 优先级:(1,1,0) = (1,0,0) + (0,1,0) */
color: purple;
}
/* 多个类选择器 */
.button.primary {
/* 优先级:(0,2,0) = (0,1,0) + (0,1,0) */
color: orange;
}
伪类和伪元素在选择器优先级计算中的地位:
/* 伪类选择器 */
a:hover {
/* 优先级:(0,1,1) = (0,1,0) + (0,0,1) */
color: blue;
}
/* 伪元素选择器 */
p::first-line {
/* 优先级:(0,0,2) = (0,0,1) + (0,0,1) */
color: green;
}
/* :not() 伪类 */
div:not(.exclude) {
/* 优先级:(0,1,1) = (0,1,0) + (0,0,1) */
color: red;
}
属性选择器的优先级与类选择器相同:
/* 类选择器 */
.text {
/* 优先级:(0,1,0) */
color: blue;
}
/* 属性选择器 */
[class="text"] {
/* 优先级:(0,1,0) */
color: green;
}
/* 两者优先级相同,后定义的规则生效 */
!important 是一个特殊的声明,它具有最高的优先级,会覆盖所有其他样式。
/* 普通声明 */
.text {
color: blue;
}
/* !important 声明 */
.text {
color: red !important;
}
/* 即使有更高优先级的选择器,!important 也会生效 */
#content {
color: green;
}
/* 结果:红色 - !important 优先级最高 */
/* 覆盖第三方库的样式 */
.third-party-component {
padding: 10px !important;
}
/* 紧急修复样式 */
.fix-urgent {
display: block !important;
}
/* 调试样式 */
.debug {
border: 2px solid red !important;
}
/* 不推荐 - 过度使用 !important */
.button {
color: white !important;
background: blue !important;
padding: 10px !important;
border: none !important;
}
/* 推荐 - 使用更高优先级的选择器 */
.button.primary {
color: white;
background: blue;
padding: 10px;
border: none;
}
/* 规则 A */
.text {
color: blue !important;
/* 优先级:(0,1,0) + !important */
}
/* 规则 B */
#content {
color: red !important;
/* 优先级:(1,0,0) + !important */
}
/* 都有 !important,比较基础优先级
* 规则 B 优先级更高
* 结果:红色
*/
内联样式(通过 style 属性设置)具有很高的优先级,仅次于 !important。
/* CSS 规则 */
.text {
color: blue;
}
/* HTML 元素 */
<p class="text" style="color: red;">这段文字是红色的</p>
/* 结果:红色 - 内联样式优先级更高 */
/* CSS 规则 */
.text {
color: blue !important;
}
/* HTML 元素 */
<p class="text" style="color: red;">这段文字是蓝色的</p>
/* 结果:蓝色 - !important 优先级最高 */
从高到低的优先级顺序:
/* 优先级层次示例 */
/* 1. !important - 最高 */
.text {
color: red !important;
}
/* 2. 内联样式 - 很高 */
<p style="color: blue;">内容</p>
/* 3. ID 选择器 - 高 */
#content {
color: green;
}
/* 4. 类选择器 - 中等 */
.text {
color: yellow;
}
/* 5. 元素选择器 - 较低 */
p {
color: purple;
}
/* 6. 通配符选择器 - 低 */
* {
color: orange;
}
/* 7. 继承 - 最低 */
body {
color: gray;
}
/* 冲突 */
.text {
color: blue;
}
.content .text {
color: green;
}
/* 解决方法 - 使用更高优先级的选择器 */
.container .content .text {
color: red;
}
/* 冲突 */
.text {
color: blue;
}
/* 解决方法 - 使用 !important */
.text {
color: red !important;
}
/* 优先级相同的规则,后定义的生效 */
.text {
color: blue;
}
.text {
color: green;
}
/* 结果:绿色 */
/* 不够具体 */
.text {
color: blue;
}
/* 更具体 */
.button.text {
color: red;
}
/* 基础按钮样式 */
.button {
padding: 10px 20px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
}
/* 主要按钮 */
.button.primary {
background: #0056b3;
}
/* 禁用按钮 */
.button:disabled {
background: #6c757d;
cursor: not-allowed;
}
/* 冲突 - 禁用的主要按钮 */
.button.primary:disabled {
/* 优先级:(0,2,1) = (0,2,0) + (0,0,1) */
background: #343a40 !important;
}
/* 导航链接基础样式 */
.nav-link {
color: white;
text-decoration: none;
padding: 10px 15px;
display: block;
}
/* 悬停效果 */
.nav-link:hover {
background: rgba(255,255,255,0.1);
}
/* 当前页面链接 */
.nav-link.active {
background: #007bff;
font-weight: bold;
}
/* 冲突 - 当前页面的悬停效果 */
.nav-link.active:hover {
/* 优先级:(0,2,1) */
background: #0056b3;
}
现代浏览器的开发者工具可以显示样式的优先级和覆盖情况:
/* 调试样式 - 高优先级 */
.debug {
border: 3px solid red !important;
background: yellow !important;
}
/* 显示选择器优先级 */
body {
counter-reset: priority;
}
/* 不同优先级的选择器 */
#header {
counter-increment: priority;
}
.text {
counter-increment: priority;
}
#header::after {
content: " 优先级: " counter(priority);
}
理解 CSS 选择器优先级对于编写可维护的 CSS 至关重要:
记住以下几点: