CSS 选择器

选择器是 CSS 的"瞄准镜"——决定每条规则作用到哪些元素。掌握常用选择器,日常开发 90% 的场景就够用了。这一篇我们把所有常用选择器系统过一遍,最后讲清最让人头疼的"优先级"问题。

1. 基础选择器

这四种是最基本的,几乎每段 CSS 都会用到。

/* 标签选择器:选中所有某类元素 */
h1 { color: #333; }
p { line-height: 1.6; }
a { color: #4f8cff; }

/* 类选择器:选中带 class="btn" 的元素(最常用) */
.btn { padding: 8px 16px; }
.card { background: #fff; }

/* ID 选择器:选中 id="hero" 的元素(页面唯一) */
#hero { background: #f0f0f0; }

/* 通配符:选中所有元素(性能差,少用) */
* { box-sizing: border-box; }

2. 一个元素可以有多个类

HTML 里 class 属性可以写多个类名,空格分隔。CSS 可以单独命中其中任何一个,也可以用"连写"要求同时具有多个类才命中——这是组合样式的关键技巧。

<!-- 一个元素可以同时有多个类,空格分隔 -->
<div class="card large highlight">内容</div>

/* 任何一个类都能选中它 */
.card { ... }
.large { ... }
.highlight { ... }

/* 连写:同时具有多个类才命中(中间无空格) */
.card.large { font-size: 1.2rem; }
.card.highlight { border-color: #ff0; }

注意 .card.large(中间无空格)和 .card .large(中间有空格)完全是两回事:前者要求"同一个元素同时具有两个类",后者是后代选择器。这是新手最容易混淆的点。

3. 组合选择器(关系)

把多个选择器用空格、>+~ 连起来,可以基于元素之间的关系选中目标。四种组合符:

/* 后代选择器(空格):nav 里的所有 a,不管嵌套多深 */
nav a { color: #4f8cff; }

/* 子代选择器(>):只选 nav 的"直接"子元素 a,不选孙级 */
nav > a { color: red; }

/* 相邻兄弟(+):紧贴在 h1 后面的第一个 p */
h1 + p { font-size: 1.1rem; }

/* 通用兄弟(~):h1 之后所有的同级 p */
h1 ~ p { color: #666; }

4. 属性选择器

根据 HTML 属性来选中元素,在做表单、链接样式时特别有用。^ 表示开头、$ 表示结尾、* 表示包含。

/* 选中带 href 属性的 a */
a[href] { color: #4f8cff; }

/* 精确匹配:href 等于某值 */
a[href="https://example.com"] { ... }

/* 以某值开头:href 以 https 开头 */
a[href^="https"] { ... }

/* 以某值结尾:src 以 .png 结尾 */
img[src$=".png"] { ... }

/* 包含某子串:class 列表里包含 active */
div[class*="active"] { ... }

5. 伪类(状态与结构)

伪类以单冒号开头,选中处于某种状态的元素——比如鼠标悬停、被选中、是第几个孩子。这是 CSS 里最丰富的能力之一。

/* :hover 光标悬停时 */
.btn:hover { background: #3a78e0; }

/* :focus 输入框获得焦点时 */
input:focus { border-color: #4f8cff; }

/* :first-child 第一个子元素 */
li:first-child { font-weight: bold; }

/* :last-child 最后一个子元素 */
li:last-child { border-bottom: none; }

/* :nth-child(n) 第 n 个子元素 */
li:nth-child(2) { color: red; }      /* 第 2 个 */
li:nth-child(odd) { background: #f5f5f5; }   /* 奇数行 */
li:nth-child(even) { background: #fff; }     /* 偶数行 */

/* :not() 排除某些元素 */
li:not(:first-child) { margin-top: 8px; }

最常用的几个::hover(悬停)、:focus(聚焦)、:first-child / :last-child(首/尾孩子)、:nth-child()(第 n 个)、:not()(排除)。

:nth-child() 的参数很灵活:2 是第 2 个,odd 是奇数行,even 是偶数行,3n 是每 3 个一次。表格斑马纹、列表间隔分隔线都靠它。

6. 伪元素

伪元素以双冒号开头,用来选中元素的某个部分——最常见的是在内容前后插入东西,或选中第一行文字。注意伪元素必须配 content 属性,即使内容为空也要写 content: ""

/* ::before 在元素内容前插入内容(必须配 content) */
.btn::before {
  content: "★";
  margin-right: 6px;
}

/* ::after 在元素内容后插入 */
.required::after {
  content: "*";
  color: red;
}

/* ::first-line 选中第一行文字 */
p::first-line { font-weight: bold; }

/* ::selection 选中用户选中的文字 */
::selection { background: #4f8cff; color: #fff; }

::before::after 非常有用:加图标、加必填星号、做装饰、清除浮动都靠它。但记住——伪元素插入的内容不能被选中复制,所以重要信息千万别用伪元素放,只用来做装饰。

7. 优先级(Specificity)

当多条规则作用到同一个元素时,浏览器怎么决定听谁的?这就靠优先级。规则有点像"计位":ID 最强,类其次,标签最弱。下面按优先级从低到高排列:

/* 优先级从低到高 */

/* 1. 标签选择器(权重 0,0,0,1) */
div { color: black; }

/* 2. 类/属性/伪类(权重 0,0,1,0) */
.box { color: blue; }

/* 3. ID(权重 0,1,0,0) */
#main { color: red; }

/* 4. 行内样式(权重 1,0,0,0,最高) */
<p style="color: green;">行内</p>

/* !important 强制最高优先级(慎用) */
.box { color: orange !important; }

具体计算方式是把选择器拆成 (a, b, c) 三位数:

从左到右逐位比较,大的赢。比如 #nav .item(1,1,0) > .menu .item:hover(0,3,0) > div ul li(0,0,3)。优先级相同时,后写的覆盖先写的。

两个忠告:

小结

选择器是 CSS 的核心武器。掌握基础(标签/类/ID)、组合(空格/>/+/~)、伪类、伪元素,加上理解优先级,你就能精准命中任何想改的元素。下一篇讲盒模型——理解了盒子,布局才算开了门。

← 上一篇 CSS 语法与引入方式

下一篇 CSS 盒模型

✈️💬