轩辕李的博客 轩辕李的博客
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • JavaScript
  • TypeScript
  • Node.js
  • Vue.js
  • 前端工程化
  • 浏览器与Web API
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

轩辕李

勇猛精进,星辰大海
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • JavaScript
  • TypeScript
  • Node.js
  • Vue.js
  • 前端工程化
  • 浏览器与Web API
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Node.js

  • Vue.js

  • 工程化

  • 浏览器与Web API

    • HTML基础-语义化标签与文档结构
    • HTML基础-文本与排版标签
    • HTML基础-列表与表格
    • HTML表单-Input类型详解
    • HTML表单-表单元素与验证
    • HTML交互-多媒体元素
    • HTML工程化-模板与组件化
    • HTML工程化-性能优化
    • CSS基础-选择器与优先级
      • 一、选择器类型
        • 1.1 基础选择器
        • 通配符选择器
        • 元素选择器
        • 类选择器
        • ID选择器
        • 1.2 组合选择器
        • 后代选择器
        • 子选择器
        • 相邻兄弟选择器
        • 通用兄弟选择器
        • 1.3 属性选择器
        • 基本属性选择器
        • 高级属性选择器
        • 1.4 伪类选择器
        • 状态伪类
        • 结构伪类
        • 其他实用伪类
        • 1.5 伪元素选择器
      • 二、选择器优先级
        • 2.1 优先级计算规则
        • 计算示例
        • 2.2 优先级比较规则
        • 2.3 优先级实战案例
      • 三、层叠规则(Cascade)
        • 3.1 样式来源
        • 1. 用户代理样式(浏览器默认)
        • 2. 用户样式(很少见)
        • 3. 作者样式(开发者编写)
        • 3.2 !important 的特殊性
        • 实际案例对比
        • 3.3 完整的层叠优先级
        • 3.4 同级别下的优先级判断
        • 3.5 实用建议
      • 四、最佳实践
        • 4.1 避免过度使用 !important
        • 4.2 保持选择器简洁
        • 4.3 使用类选择器而非ID选择器
        • 4.4 合理使用组合选择器
        • 4.5 利用伪类减少类名
        • 4.6 使用属性选择器处理特殊情况
      • 五、调试技巧
        • 5.1 使用浏览器开发者工具
        • 5.2 常见问题排查
      • 六、浏览器兼容性
      • 七、总结
    • CSS基础-盒模型与布局基础
    • CSS基础-单位与颜色系统
    • CSS基础-文本与字体
    • CSS基础-背景、列表与表格样式
    • CSS布局-Flexbox完全指南
    • CSS布局-Grid网格布局
    • CSS布局-响应式设计实践
    • CSS进阶-动画与过渡
    • CSS进阶-渐变与阴影效果
    • CSS进阶-Transform与3D变换
    • CSS进阶-滤镜与混合模式
    • 现代CSS-CSS预处理器对比
    • 现代CSS-CSS-in-JS方案
    • 现代CSS-原子化CSS与Tailwind
    • CSS工程化-架构与规范
    • CSS工程化-性能优化
    • CSS工程化-PostCSS实战指南
    • Web API基础-DOM操作完全指南
    • Web API基础-事件处理与委托
    • Web API基础-BOM与浏览器环境
    • Web API存储-客户端存储方案
    • Web API网络-HTTP请求详解
    • Web API网络-实时通信方案
    • Web API交互-用户体验增强
    • HTML&CSS历代版本新特性
  • 前端
  • 浏览器与Web API
轩辕李
2019-03-06
目录

CSS基础-选择器与优先级

CSS选择器是前端开发的基础,理解选择器类型和优先级规则对于编写可维护的样式代码至关重要。

本文将系统介绍CSS选择器的各种类型、优先级计算规则以及实际应用中的最佳实践。

# 一、选择器类型

# 1.1 基础选择器

# 通配符选择器

* {
  margin: 0;
  padding: 0;
}

通配符选择器 * 匹配所有元素,常用于重置默认样式。但要注意性能问题,避免过度使用。

# 元素选择器

p {
  color: #333;
  line-height: 1.6;
}

h1 {
  font-size: 2em;
  font-weight: bold;
}

元素选择器直接使用HTML标签名,是最基础的选择器类型。

# 类选择器

.container {
  width: 100%;
  max-width: 1200px;
}

.btn-primary {
  background-color: #007bff;
  color: white;
}

类选择器使用 . 前缀,是实际开发中最常用的选择器,可复用性强。

# ID选择器

#header {
  position: fixed;
  top: 0;
  width: 100%;
}

#main-content {
  padding: 20px;
}

ID选择器使用 # 前缀,优先级最高,但不建议过度使用,因为会降低样式的可复用性。

# 1.2 组合选择器

# 后代选择器

/* 选择 .container 内所有的 p 元素 */
.container p {
  margin-bottom: 1em;
}

/* 多层嵌套 */
nav ul li a {
  text-decoration: none;
}

后代选择器使用空格分隔,匹配所有符合条件的后代元素,无论嵌套层级。

# 子选择器

/* 只选择直接子元素 */
.nav > li {
  display: inline-block;
}

ul > li > a {
  color: #333;
}

子选择器使用 > 符号,只匹配直接子元素,比后代选择器更精确。

# 相邻兄弟选择器

/* 选择紧跟在 h1 后面的 p 元素 */
h1 + p {
  font-size: 1.2em;
  color: #666;
}

相邻兄弟选择器使用 + 符号,只匹配紧邻的下一个兄弟元素。

# 通用兄弟选择器

/* 选择 h1 后面所有的 p 元素 */
h1 ~ p {
  margin-left: 20px;
}

通用兄弟选择器使用 ~ 符号,匹配后面所有的兄弟元素。

# 1.3 属性选择器

# 基本属性选择器

/* 存在 title 属性 */
[title] {
  cursor: help;
}

/* 完全匹配 */
[type="text"] {
  border: 1px solid #ccc;
}

/* 包含特定词 */
[class~="btn"] {
  padding: 5px 10px;
}

# 高级属性选择器

/* 以特定值开头 */
[href^="https"] {
  color: green;
}

/* 以特定值结尾 */
[src$=".png"] {
  border: 1px solid #ddd;
}

/* 包含特定字符串 */
[href*="example"] {
  font-weight: bold;
}

/* 以特定值开头(包括连字符分隔) */
[lang|="zh"] {
  font-family: "Microsoft YaHei";
}

# 1.4 伪类选择器

# 状态伪类

/* 链接状态 */
a:link { color: blue; }
a:visited { color: purple; }
a:hover { color: red; }
a:active { color: orange; }

/* 表单状态 */
input:focus {
  border-color: #007bff;
  outline: none;
}

input:disabled {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

input:checked + label {
  font-weight: bold;
}

# 结构伪类

/* 第一个/最后一个子元素 */
li:first-child {
  margin-top: 0;
}

li:last-child {
  border-bottom: none;
}

/* 唯一子元素 */
p:only-child {
  margin: 0;
}

/* nth 选择器 */
tr:nth-child(odd) {
  background-color: #f9f9f9;
}

tr:nth-child(even) {
  background-color: #fff;
}

/* 每3个元素 */
li:nth-child(3n) {
  color: red;
}

/* 从第4个开始 */
li:nth-child(n+4) {
  display: none;
}

/* 前3个 */
li:nth-child(-n+3) {
  font-weight: bold;
}

# 其他实用伪类

/* 非选择器 */
div:not(.special) {
  opacity: 0.5;
}

/* 空元素 */
p:empty {
  display: none;
}

/* 目标元素(锚点) */
:target {
  background-color: yellow;
}

# 1.5 伪元素选择器

/* 首字母 */
p::first-letter {
  font-size: 2em;
  font-weight: bold;
  float: left;
}

/* 首行 */
p::first-line {
  color: #666;
}

/* 前后插入内容 */
.icon::before {
  content: "→ ";
  color: #007bff;
}

.external-link::after {
  content: " ↗";
  font-size: 0.8em;
}

/* 选中的文本 */
::selection {
  background-color: #007bff;
  color: white;
}

/* 占位符 */
input::placeholder {
  color: #999;
  font-style: italic;
}

# 二、选择器优先级

# 2.1 优先级计算规则

CSS优先级(特异性)通过四个数值来计算:(a, b, c, d)

  • a: 内联样式(style属性) = 1000
  • b: ID选择器的数量 = 100
  • c: 类选择器、属性选择器、伪类的数量 = 10
  • d: 元素选择器、伪元素的数量 = 1

# 计算示例

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

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

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

/* (0, 0, 1, 1) = 11 */
p.class { }

/* (0, 1, 1, 1) = 111 */
#id .class p { }

/* (0, 2, 1, 0) = 210 */
#nav #menu .item { }

/* (1, 0, 0, 0) = 1000 */
<p style="color: red;"></p>

# 2.2 优先级比较规则

  1. 从左到右依次比较:先比较a,相同则比较b,以此类推
  2. !important 优先级最高:覆盖所有其他规则
  3. 相同优先级,后定义的覆盖先定义的
  4. 通配符选择器、组合器(+、>、~、空格)不增加优先级
/* 优先级: (0, 0, 1, 0) = 10 */
.text {
  color: blue;
}

/* 优先级: (0, 1, 0, 0) = 100,会覆盖上面的规则 */
#content {
  color: red;
}

/* 优先级: (0, 1, 1, 1) = 111,会覆盖上面的规则 */
#content .text p {
  color: green;
}

/* !important 优先级最高 */
.text {
  color: yellow !important; /* 最终生效 */
}

# 2.3 优先级实战案例

<html>
  <div id="app-dv" class="container">
    <p class="text highlight">Hello World (最终显示红色)</p>
    <div style="margin-top: 20px; padding: 10px; background: #f5f5f5; font-size: 14px;">
      <div><strong>优先级计算过程:</strong></div>
      <div>• p {} → (0,0,0,1) = 1</div>
      <div>• .text {} → (0,0,1,0) = 10</div>
      <div>• .text.highlight {} → (0,0,2,0) = 20</div>
      <div>• .container .highlight {} → (0,0,2,1) = 21</div>
      <div>• #app-dv p {} → (0,1,0,1) = 101</div>
      <div>• #app-dv .text {} → (0,1,1,1) = 111 ✅ 最高优先级</div>
    </div>
  </div>
</html>
<style>
  /* 优先级: (0, 0, 0, 1) = 1 */
  p {
    color: black;
  }

  /* 优先级: (0, 0, 1, 0) = 10 */
  .text {
    color: blue;
  }

  /* 优先级: (0, 0, 2, 0) = 20 */
  .text.highlight {
    color: green;
  }

  /* 优先级: (0, 0, 2, 1) = 21 */
  .container .highlight {
    color: orange;
  }

  /* 优先级: (0, 1, 0, 1) = 101 */
  #app-dv p {
    color: purple;
  }

  /* 优先级: (0, 1, 1, 1) = 111 */
  #app-dv .text {
    color: red; /* 最终生效 */
  }
</style>

# 三、层叠规则(Cascade)

当多个规则应用于同一元素时,CSS使用以下顺序决定最终样式:

# 3.1 样式来源

CSS样式有三个来源,它们的优先级从低到高:

# 1. 用户代理样式(浏览器默认)

/* 浏览器内置的默认样式,例如: */
p {
  display: block;
  margin-block-start: 1em;
  margin-block-end: 1em;
}

a {
  color: blue;
  text-decoration: underline;
}

这是浏览器自带的样式,优先级最低。

# 2. 用户样式(很少见)

用户通过浏览器设置或浏览器扩展自定义的样式,例如:

  • 用户设置了更大的默认字体
  • 用户安装了"夜间模式"扩展
  • 无障碍辅助工具修改的样式

# 3. 作者样式(开发者编写)

/* 我们开发者写的CSS */
p {
  margin: 0;
  line-height: 1.6;
}

a {
  color: #007bff;
  text-decoration: none;
}

这是我们日常编写的样式,正常情况下优先级最高。

优先级顺序:

用户代理样式 < 用户样式 < 作者样式(开发者样式)

# 3.2 !important 的特殊性

当使用 !important 时,优先级顺序会反转:

作者样式!important < 用户样式!important < 用户代理样式!important

为什么会反转?

这是为了保护用户的选择权。例如:

  • 用户因视力问题设置了 font-size: 20px !important
  • 开发者的样式不应该覆盖用户的无障碍需求

# 实际案例对比

<p class="text">这是一段文字</p>

场景1:没有!important

/* 用户代理样式(浏览器默认) */
p { color: black; }

/* 用户样式(用户设置) */
p { color: red; }

/* 作者样式(开发者编写) */
.text { color: blue; }

/* 结果:蓝色(作者样式优先级最高) */

场景2:使用!important

/* 作者样式(开发者编写) */
.text { color: blue !important; }

/* 用户样式(用户通过浏览器设置) */
p { color: red !important; }

/* 结果:红色(用户的!important优先级更高) */

# 3.3 完整的层叠优先级

综合考虑所有因素,完整的优先级从低到高:

  1. 用户代理样式(浏览器默认)
  2. 用户样式
  3. 作者样式(开发者编写)
  4. 作者样式 + !important
  5. 用户样式 + !important
  6. 用户代理样式 + !important

# 3.4 同级别下的优先级判断

在同一来源的样式中,按以下规则判断:

  1. 优先级(特异性):按照前面介绍的规则计算
  2. 源码顺序:相同优先级时,后面的覆盖前面的
/* 示例:源码顺序的影响 */
.button {
  background-color: blue;
  color: white;
}

.button {
  background-color: red; /* 会覆盖上面的蓝色 */
}

# 3.5 实用建议

在日常开发中:

  • 用户代理样式:通常会用CSS Reset或Normalize.css重置
  • 用户样式:基本不需要考虑,但要注意无障碍性
  • 作者样式:我们主要关注这一层的优先级计算
  • !important:尽量避免使用,除非确实需要覆盖第三方库样式

# 四、最佳实践

# 4.1 避免过度使用 !important

/* ❌ 不推荐 */
.button {
  color: red !important;
}

/* ✅ 推荐:提高选择器优先级 */
.nav .button {
  color: red;
}

# 4.2 保持选择器简洁

/* ❌ 不推荐:过于具体 */
body div.container ul li a.link {
  color: blue;
}

/* ✅ 推荐:简洁明了 */
.nav-link {
  color: blue;
}

# 4.3 使用类选择器而非ID选择器

/* ❌ 不推荐:难以复用 */
#header {
  padding: 20px;
}

/* ✅ 推荐:可复用 */
.header {
  padding: 20px;
}

# 4.4 合理使用组合选择器

/* ✅ 推荐:清晰的层级关系 */
.card > .card-header {
  border-bottom: 1px solid #ddd;
}

.card .card-body p {
  line-height: 1.6;
}

# 4.5 利用伪类减少类名

/* ❌ 不推荐 */
.list-item-first { }
.list-item-last { }

/* ✅ 推荐 */
.list-item:first-child { }
.list-item:last-child { }

# 4.6 使用属性选择器处理特殊情况

/* 外部链接添加图标 */
a[href^="http"]::after {
  content: "↗";
  margin-left: 4px;
}

/* PDF链接添加图标 */
a[href$=".pdf"]::before {
  content: "📄 ";
}

# 五、调试技巧

# 5.1 使用浏览器开发者工具

  • 查看计算后的样式(Computed)可以看到最终生效的属性
  • 查看样式规则(Styles)可以看到被覆盖的规则(带删除线)
  • 使用选择器过滤器快速定位样式来源

# 5.2 常见问题排查

问题1:样式不生效

  • 检查选择器是否正确
  • 检查优先级是否被覆盖
  • 检查CSS语法是否正确
  • 检查是否有缓存问题

问题2:优先级混乱

  • 避免过度嵌套
  • 减少ID选择器使用
  • 统一命名规范(如BEM)
  • 使用CSS预处理器管理

问题3:!important 滥用

  • 重构选择器,提高优先级
  • 调整CSS加载顺序
  • 使用更具体的选择器

# 六、浏览器兼容性

现代浏览器对CSS选择器的支持已经非常完善:

选择器类型 Chrome Firefox Safari Edge
基础选择器 ✅ ✅ ✅ ✅
伪类选择器 ✅ ✅ ✅ ✅
伪元素(::) ✅ ✅ ✅ ✅
:not() ✅ ✅ ✅ ✅
:nth-child() ✅ ✅ ✅ ✅

注意事项:

  • IE11及以下版本对部分CSS3选择器支持不完善
  • 伪元素推荐使用双冒号 :: 而非单冒号 :
  • 使用Can I Use (opens new window)检查兼容性

# 七、总结

CSS选择器是构建网页样式的基础,掌握以下要点:

  1. 选择器类型:从基础到高级,灵活运用各种选择器
  2. 优先级计算:理解(a,b,c,d)四元组规则,避免优先级冲突
  3. 层叠规则:掌握来源、优先级、源码顺序的层叠逻辑
  4. 最佳实践:保持选择器简洁,避免!important,提高代码可维护性
  5. 调试技巧:善用开发者工具,快速定位样式问题

深入理解CSS选择器和优先级,能让你写出更优雅、更易维护的样式代码。

祝你变得更强!

编辑 (opens new window)
#CSS
上次更新: 2025/11/20
HTML工程化-性能优化
CSS基础-盒模型与布局基础

← HTML工程化-性能优化 CSS基础-盒模型与布局基础→

最近更新
01
AI编程时代的一些心得
09-11
02
Claude Code与Codex的协同工作
09-01
03
Claude Code 最佳实践(个人版)
08-01
更多文章>
Theme by Vdoing | Copyright © 2018-2025 京ICP备2021021832号-2 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式