CSS 优先级

学习

CSS 优先级

2026-02-23/0/ 编辑


CSS 优先级

1. 概念

CSS 优先级(Specificity) 是指当多个样式规则应用于同一个元素时,浏览器决定哪个样式生效的规则。

优先级是 CSS 层叠性的核心机制之一,它决定了样式冲突时的最终效果。


2. 优先级计算规则

2.1 权重值系统

选择器类型权重值说明
!important∞ (无穷大)最高优先级,慎用
内联样式1000<div style="">
ID 选择器100#header
类选择器10.container
属性选择器10[type="text"]
伪类选择器10:hover, :focus
标签选择器1div, p
伪元素选择器1::before, ::after
通配符选择器0*
关系选择器0+, >, ~, (空格)

2.2 优先级计算示例

/* 权重: 1 */
div { color: red; }

/* 权重: 10 */
.box { color: blue; }

/* 权重: 11 (10 + 1) */
div.box { color: green; }

/* 权重: 100 */
#header { color: orange; }

/* 权重: 110 (100 + 10) */
#header.active { color: purple; }

/* 权重: 111 (100 + 10 + 1) */
#header.active a { color: pink; }

/* 权重: 20 (10 + 10) */
.nav.active { background: blue; }

/* 权重: 21 (10 + 10 + 1) */
.nav.active ul { background: green; }

3. 优先级计算方法

3.1 三位数表示法

将优先级表示为 (A, B, C) 三位数:

  • A: ID 选择器数量
  • B: 类选择器、属性选择器、伪类选择器数量
  • C: 标签选择器、伪元素选择器数量

计算示例

/* (0, 0, 1) = 1 */
div { }

/* (0, 1, 0) = 10 */
.box { }

/* (0, 1, 1) = 11 */
div.box { }

/* (1, 0, 0) = 100 */
#header { }

/* (1, 1, 0) = 110 */
#header.active { }

/* (1, 1, 1) = 111 */
#header.active a { }

/* (0, 2, 1) = 21 */
.nav.active ul { }

3.2 比较规则

  1. 先比较 A (ID 选择器数量)
  2. 如果 A 相同,比较 B (类选择器数量)
  3. 如果 B 相同,比较 C (标签选择器数量)
  4. 如果全部相同,后面的覆盖前面的

比较示例

/* (0, 1, 1) = 11 */
div.box { color: red; }

/* (1, 0, 0) = 100 ✓ 更高优先级 */
#header { color: blue; }

/* 结果: 蓝色生效 */

---

/* (0, 2, 0) = 20 */
.nav.active { color: red; }

/* (0, 1, 1) = 11 */
div.box { color: blue; }

/* 结果: 红色生效 (20 > 11) */

---

/* (1, 1, 0) = 110 */
#header.active { color: red; }

/* (1, 1, 1) = 111 ✓ 更高优先级 */
#header.active a { color: blue; }

/* 结果: 蓝色生效 (111 > 110) */

4. 特殊情况

4.1 !important 优先级

/* 普通 */
#header { color: red; }  /* 权重: 100 */

/* !important 覆盖一切 */
.container { color: blue !important; }  /* 权重: 10,但 !important 生效 */

/* 结果: 蓝色生效 */

注意:

  • !important 会破坏正常的层叠性,应尽量避免使用
  • 如果多个样式都有 !important,则按照普通优先级规则比较

4.2 相同优先级,后覆盖前

/* 权重相同: 10 */
.box { color: red; }
.box { color: blue; }  /* 后面的覆盖前面的 */

/* 结果: 蓝色生效 */

4.3 内联样式优先级

<style>
  .box { color: red; }  /* 权重: 10 */
</style>

<div class="box" style="color: blue">  <!-- 权重: 1000 -->
  这段文字是蓝色
</div>

<!-- 结果: 内联样式生效 -->

4.4 继承的样式优先级最低

<style>
  body { color: red; }  /* 继承的样式 */

  div { color: blue; }  /* 权重: 1,但覆盖继承的红色 */
</style>

<body>
  <div>这段文字是蓝色</div>
</body>

<!-- 结果: 蓝色生效,直接设置的样式优先级高于继承 -->

5. 选择器组合的优先级

5.1 后代选择器

/* 权重: 2 (1 + 1) */
div p { color: red; }

/* 权重: 11 (10 + 1) */
div .box { color: blue; }

/* 权重: 12 (1 + 10 + 1) */
div .box p { color: green; }

/* 权重: 101 (100 + 1) */
#header p { color: orange; }

5.2 子代选择器

/* 权重: 2 (1 + 1) */
div > p { color: red; }

/* 权重: 11 (10 + 1) */
div > .box { color: blue; }

/* 权重: 12 (1 + 10 + 1) */
div > .box > p { color: green; }

注意: 子代选择器 > 和后代选择器 (空格) 的权重计算方式相同,关系选择器本身不增加权重。

5.3 兄弟选择器

/* 权重: 2 (1 + 1) */
div + p { color: red; }

/* 权重: 11 (10 + 1) */
.box + a { color: blue; }

/* 权重: 2 (1 + 1) */
div ~ p { color: green; }

5.4 伪类和伪元素

/* 权重: 11 (10 + 1) */
a:hover { color: red; }

/* 权重: 2 (1 + 1) */
p::before { content: ''; }

/* 权重: 12 (10 + 1 + 1) */
.box:hover span { color: blue; }

/* 权重: 20 (10 + 10) */
.box.active { color: green; }

5.5 属性选择器

/* 权重: 10 */
input[type="text"] { }

/* 权重: 10 */
a[href^="http"] { }

/* 权重: 10 */
div[data-id="123"] { }

/* 权重: 20 (10 + 10) */
input[type="text"]:focus { }

6. 实战应用

应用 1: 按钮样式系统

/* 基础按钮 - 权重: 10 */
.btn {
  padding: 10px 20px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

/* 大按钮 - 权重: 20 (10 + 10) */
.btn.btn-lg {
  padding: 15px 30px;
  font-size: 1.2em;
}

/* 小按钮 - 权重: 20 */
.btn.btn-sm {
  padding: 5px 15px;
  font-size: 0.9em;
}

/* 主题按钮 - 权重: 20 */
.btn.btn-primary {
  background: #007bff;
}

/* 成功按钮 - 权重: 20 */
.btn.btn-success {
  background: #28a745;
}

/* 危险按钮 - 权重: 20 */
.btn.btn-danger {
  background: #dc3545;
}

/* 禁用状态 - 权重: 20 */
.btn.disabled {
  background: #ccc;
  cursor: not-allowed;
  pointer-events: none;
}

应用 2: 导航栏样式

/* 导航容器 - 权重: 10 */
.nav {
  display: flex;
  background: #333;
  padding: 0 20px;
}

/* 导航链接 - 权重: 11 (10 + 1) */
.nav a {
  display: block;
  padding: 15px;
  color: white;
  text-decoration: none;
  transition: background 0.3s;
}

/* 悬停效果 - 权重: 11 */
.nav a:hover {
  background: rgba(255, 255, 255, 0.1);
}

/* 激活状态 - 权重: 20 (10 + 10) */
.nav a.active {
  background: #007bff;
  font-weight: bold;
}

/* 禁用链接 - 权重: 20 */
.nav a.disabled {
  color: #999;
  pointer-events: none;
}

应用 3: 表单样式

/* 表单输入框 - 权重: 11 (10 + 1) */
.form-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 16px;
}

/* 聚焦状态 - 权重: 11 */
.form-input:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);
}

/* 错误状态 - 权重: 20 (10 + 10) */
.form-input.error {
  border-color: #dc3545;
  background: #fff5f5;
}

/* 成功状态 - 权重: 20 */
.form-input.success {
  border-color: #28a745;
  background: #f5fff5;
}

/* 必填标记 - 权重: 22 (10 + 10 + 1 + 1) */
.form-input.required:focus::placeholder {
  color: #dc3545;
}

应用 4: 卡片组件

/* 卡片 - 权重: 10 */
.card {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

/* 卡片标题 - 权重: 11 (10 + 1) */
.card-title {
  padding: 20px;
  font-size: 1.5em;
  font-weight: bold;
  border-bottom: 1px solid #eee;
}

/* 卡片内容 - 权重: 11 */
.card-body {
  padding: 20px;
  line-height: 1.6;
  color: #666;
}

/* 卡片底部 - 权重: 11 */
.card-footer {
  padding: 20px;
  border-top: 1px solid #eee;
  background: #f9f9f9;
}

/* 带边框的卡片 - 权重: 20 */
.card.bordered {
  border: 1px solid #ddd;
  box-shadow: none;
}

/* 主要卡片 - 权重: 20 */
.card.primary {
  border: 2px solid #007bff;
}

7. 优先级调试技巧

7.1 浏览器开发者工具

  1. 打开开发者工具 (F12)
  2. 选择元素 (点击元素或使用 Ctrl+Shift+C)
  3. 查看 Styles 面板

    • 显示所有应用的选择器
    • 被划掉的样式表示被覆盖
    • 按优先级从高到低排序
  4. 查看 Computed 面板

    • 显示最终生效的样式
    • 可以追溯到样式来源

7.2 使用注释记录权重

/* 权重: 10 */
.box { }

/* 权重: 100 */
#container { }

/* 权重: 20 (10 + 10) */
.nav.active { }

/* 权重: 111 (100 + 10 + 1) */
#header.main a { }

7.3 添加调试样式

/* 调试: 高亮显示元素 */
.debug {
  border: 2px solid red !important;
  background: yellow !important;
}

/* 查看优先级 */
.test {
  color: red;    /* 权重: 10 */
  color: blue !important;  /* 权重: ∞ - 覆盖 */
}

8. 注意事项

8.1 避免过高优先级

/* ❌ 不推荐: 过高的优先级,难以覆盖 */
.container .sidebar .widget .title {
  color: red;  /* 权重: 30 (0, 3, 0) */
}

/* ✅ 推荐: 合理的优先级 */
.widget-title {
  color: red;  /* 权重: 10 (0, 1, 0) */
}

8.2 避免 ID 选择器

/* ❌ 不推荐: ID 选择器优先级过高 */
#header {
  background: blue;
}

#header .nav {
  color: white;  /* 需要更高优先级才能覆盖 */
}

/* ✅ 推荐: 使用类选择器 */
.header {
  background: blue;
}

.header .nav {
  color: white;  /* 容易覆盖 */
}

8.3 慎用 !important

/* ❌ 不推荐: 滥用 !important */
.one .two .three .text {
  color: red !important;
}

.another .text {
  color: blue !important;  /* 只能用 !important 覆盖 */
}

/* ✅ 推荐: 优化选择器 */
.highlight-text {
  color: red;
}

.secondary-text {
  color: blue;  /* 正常覆盖 */
}

8.4 保持选择器简洁

/* ❌ 不推荐: 过度复杂的选择器 */
div ul li a span.highlight {
  color: red;  /* 权重: 14 (0, 1, 3) */
}

/* ✅ 推荐: 简洁的选择器 */
.highlight {
  color: red;  /* 权重: 10 (0, 1, 0) */
}

9. 常见问题解答

Q1: 为什么我的样式不生效?

A: 检查:

  1. 选择器是否正确
  2. 优先级是否足够
  3. 是否被其他更高优先级的样式覆盖
  4. 是否有语法错误
  5. 使用开发者工具查看

Q2: 何时应该使用 !important?

A: 仅在以下情况使用:

  • 需要覆盖第三方库样式
  • 紧急修复(临时方案)
  • 打印样式覆盖
  • 用户自定义样式

Q3: 如何计算复杂选择器的优先级?

A:

  1. 统计 ID 选择器数量 (A)
  2. 统计类、属性、伪类选择器数量 (B)
  3. 统计标签、伪元素选择器数量 (C)
  4. 比较 (A, B, C) 三位数

Q4: 继承的样式优先级是多少?

A: 继承的样式优先级最低,低于任何直接设置的样式,即使直接设置的样式权重为 0。

Q5: 同优先级时,怎么决定哪个生效?

A:

  1. 后面的覆盖前面的
  2. 如果是不同 CSS 文件,后引入的覆盖先引入的
  3. 内联样式 > 内部样式 > 外部样式(同优先级时)

10. 最佳实践

10.1 选择器优先级策略

/* 1. 使用类选择器为主 */
.card { }
.btn { }
.nav { }

/* 2. 组合类选择器提高优先级 */
.card.primary { }
.btn.active { }
.nav.main { }

/* 3. 避免使用 ID 选择器 */
/* ❌ #header { } */
/* ✅ .header { } */

/* 4. 保持选择器简洁 */
/* ❌ div ul li a { } */
/* ✅ .nav-link { } */

10.2 CSS 架构建议

/* 1. 重置样式 */
* { margin: 0; padding: 0; }

/* 2. 基础样式 (低优先级) */
body { font-size: 16px; }
a { color: #007bff; }

/* 3. 组件样式 (中优先级) */
.card { }
.btn { }

/* 4. 修饰符 (中优先级) */
.card.primary { }
.btn.large { }

/* 5. 状态样式 (中优先级) */
.btn:hover { }
.btn.active { }

/* 6. 页面样式 (高优先级) */
.home-page .hero { }
.about-page .content { }

/* 7. 紧急修复 (!important - 慎用) */
.error { color: red !important; }

10.3 命名规范

/* BEM 命名法 */
.block { }              /* 块 */
.block__element { }     /* 元素 */
.block--modifier { }    /* 修饰符 */

/* 示例 */
.card { }
.card__title { }
.card__body { }
.card--primary { }
.card--bordered { }

11. 总结

CSS 优先级关键要点:

  1. 权重系统:

    • !important: ∞
    • 内联样式: 1000
    • ID 选择器: 100
    • 类/属性/伪类: 10
    • 标签/伪元素: 1
    • 通配符/关系: 0
  2. 计算方法:

    • 表示为 (A, B, C) 三位数
    • A: ID 数量
    • B: 类/属性/伪类数量
    • C: 标签/伪元素数量
  3. 比较规则:

    • 先比 A,再比 B,最后比 C
    • 相同优先级,后覆盖前
    • !important 优先级最高
  4. 注意事项:

    • 避免过高优先级
    • 慎用 ID 选择器
    • 慎用 !important
    • 保持选择器简洁
  5. 最佳实践:

    • 使用类选择器为主
    • 保持选择器简洁
    • 合理规划 CSS 架构
    • 使用 BEM 命名法
  6. 调试技巧:

    • 使用浏览器开发者工具
    • 添加注释记录权重
    • 使用调试样式