Skip to content

CSS 选择器及优先级详解

CSS 选择器是样式表的核心组成部分,它们决定了样式规则应用到哪些 HTML 元素上。理解选择器的工作原理及其优先级规则,对于编写可维护且高效的 CSS 至关重要。

基本选择器

基本选择器是 CSS 中最基础也是最常用的选择器类型:

元素选择器

通过 HTML 元素名称匹配元素:

css
p {
  color: #333;
}

div {
  margin: 10px;
}

类选择器

通过元素的 class 属性值匹配元素,以 . 开头:

css
.button {
  padding: 8px 16px;
}

.highlight {
  background-color: yellow;
}

ID 选择器

通过元素的 id 属性值匹配元素,以 # 开头(一个文档中 ID 应唯一):

css
#header {
  height: 60px;
}

#logo {
  width: 120px;
}

通用选择器

匹配文档中的所有元素,以 * 表示:

css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

属性选择器

根据元素的属性及属性值匹配元素:

css
/* 匹配具有 title 属性的元素 */
[title] {
  border: 1px dotted #ccc;
}

/* 匹配 href 属性值为 "https://example.com" 的元素 */
a[href="https://example.com"] {
  color: #0066cc;
}

/* 匹配 class 属性值包含 "menu" 的元素 */
[class*="menu"] {
  display: flex;
}

属性选择器支持多种匹配模式:

  • [attr]:存在指定属性
  • [attr=value]:属性值等于指定值
  • [attr~=value]:属性值包含指定单词
  • [attr|=value]:属性值以指定值开头(或后跟连字符)
  • [attr^=value]:属性值以指定值开头
  • [attr$=value]:属性值以指定值结尾
  • [attr*=value]:属性值包含指定子串

组合选择器

组合选择器用于选择满足特定关系的元素:

后代选择器

选择祖先元素内的所有后代元素,使用空格分隔:

css
/* 选择 .container 内的所有 p 元素 */
.container p {
  line-height: 1.6;
}

子选择器

选择父元素的直接子元素,使用 > 分隔:

css
/* 选择 ul 的直接子元素 li */
ul > li {
  list-style: none;
}

相邻兄弟选择器

选择紧接在指定元素后的兄弟元素,使用 + 分隔:

css
/* 选择 h2 后面紧接的 p 元素 */
h2 + p {
  font-weight: bold;
}

通用兄弟选择器

选择指定元素后的所有兄弟元素,使用 ~ 分隔:

css
/* 选择 .feature 后面的所有 .description 元素 */
.feature ~ .description {
  margin-left: 20px;
}

伪类选择器

伪类用于定义元素的特殊状态,以 : 开头:

状态伪类

css
/* 未访问的链接 */
a:link {
  color: blue;
}

/* 已访问的链接 */
a:visited {
  color: purple;
}

/* 鼠标悬停时 */
a:hover {
  text-decoration: underline;
}

/* 元素被激活时 */
a:active {
  color: red;
}

/* 获得焦点的元素 */
input:focus {
  border-color: #66afe9;
}

结构伪类

css
/* 选择第一个子元素 */
li:first-child {
  border-top: 1px solid #eee;
}

/* 选择最后一个子元素 */
li:last-child {
  border-bottom: 1px solid #eee;
}

/* 选择第 n 个子元素(n 从 1 开始) */
tr:nth-child(2n) {
  background-color: #f9f9f9;
}

/* 选择没有子元素的元素 */
div:empty {
  display: none;
}

其他常用伪类

css
/* 选择当前选中的元素 */
:target {
  background-color: #fff3cd;
}

/* 选择不匹配指定选择器的元素 */
:not(.exclude) {
  opacity: 1;
}

/* 选择启用状态的元素 */
button:enabled {
  cursor: pointer;
}

/* 选择禁用状态的元素 */
button:disabled {
  opacity: 0.7;
}

伪元素选择器

伪元素的特定部分设置样式,以 :: 开头:

css
/* 选择元素的第一个字母 */
p::first-letter {
  font-size: 1.5em;
  font-weight: bold;
}

/* 选择元素的第一行 */
p::first-line {
  text-transform: uppercase;
}

/* 在元素内容前插入内容 */
.badge::before {
  content: "New: ";
  font-weight: bold;
}

/* 在元素内容后插入内容 */
.price::after {
  content: " $";
}

/* 选择元素的高亮部分 */
::selection {
  background-color: #b3d4fc;
}

选择器优先级

当多个选择器匹配同一个元素时,优先级决定了哪个样式规则会被应用。优先级可以理解为一个四元组 (a, b, c, d),优先级从高到低依次比较:

  1. 内联样式 (a):元素的 style 属性中的样式,优先级最高
  2. ID 选择器 (b):每个 ID 选择器贡献 1 分
  3. 类选择器、属性选择器、伪类 (c):每个该类型选择器贡献 1 分
  4. 元素选择器、伪元素 (d):每个该类型选择器贡献 1 分

优先级计算示例

css
/* (0, 0, 0, 1) */
p { . . . }

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

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

/* (0, 1, 0, 0) */
#id { . . . }

/* (0, 1, 1, 1) */
div#id .class { . . . }

/* (1, 0, 0, 0) - 内联样式 */
/* style 属性中的样式 */

重要规则

  • !important 可以覆盖任何优先级,但应谨慎使用
  • 相同优先级时,后定义的规则会覆盖先定义的规则
  • 通用选择器 (*)、组合符 (+, >, ~, 空格) 不影响优先级
  • 通配符属性选择器 [attr] 与类选择器优先级相同
css
/* 即使类选择器后定义,!important 仍会优先 */
p {
  color: red !important;
}

.highlight {
  color: blue;
}

最佳实践

  1. 优先使用低优先级选择器:减少 ID 选择器和 !important 的使用,提高样式的可复用性
  2. 保持选择器简洁:避免过度嵌套,提高性能和可维护性
  3. 使用类设计组件:采用 BEM 等命名规范,使选择器既明确又具有适当优先级
  4. 避免内联样式:便于维护和覆盖,分离结构与样式

尘埃虽微,积之成集;问题虽小,记之为鉴。 雾中低语,心之所向;思绪飘渺,皆可成章。