CSS Handbook · 选择器

第二章 / 2.4 伪类选择器

第二章 · 2.4 节

伪类选择器


伪类以冒号 : 开头,描述元素的某种"状态"或"结构位置",而这种状态往往无法通过 class 或 HTML 结构直接体现——比如鼠标是否悬停、是不是第一个子元素。

交互状态伪类

伪类触发条件
:hover鼠标悬停在元素上
:active元素被按下的瞬间
:focus元素获得键盘 / 程序焦点
:focus-visible仅在焦点应被"可见"呈现时触发(如键盘 Tab)
:visited链接已被访问过
.btn:hover { background: #3f5d54; }
.btn:focus-visible { outline: 2px solid #8a5a2e; }
可访问性请始终保留 :focus-visible 的可见轮廓样式,键盘用户依赖它判断当前焦点位置,移除它会造成严重的可用性问题。

结构性伪类

伪类含义
:first-child是父元素的第一个子元素
:last-child是父元素的最后一个子元素
:only-child是父元素唯一的子元素
:first-of-type是同类型标签中第一个
:empty没有任何子节点(含文本)
:root文档根元素,即 <html>
li:not(:last-child) {
  border-bottom: 1px solid #c9cabf;
}
效果预览:除最后一项外都有下边框
选择器
伪元素
媒体查询

nth-child 公式详解

:nth-child(An+B) 是结构性伪类中最强大也最容易混淆的一个,其中 n 从 0 开始自增。

写法命中项
:nth-child(2n)第 2、4、6… 个(偶数)
:nth-child(2n+1)第 1、3、5… 个(奇数)
:nth-child(3n)第 3、6、9… 个
:nth-child(-n+3)前 3 个
:nth-last-child(1)倒数第 1 个,等价于 :last-child
/* 斑马纹表格 */
tr:nth-child(even) {
  background: #e7e8e1;
}
易错点:nth-child 是在"所有兄弟元素"中计数,与标签类型无关;若只想在同类型标签中计数,需要使用 :nth-of-type。

表单相关伪类

input:required { border-color: #8a5a2e; }
input:invalid  { border-color: #b3452c; }
input:checked + label { color: #3f5d54; }
input:disabled { opacity: .5; }

常用的还有 :placeholder-shown(占位符可见时)与 :in-range / :out-of-range(数值是否在 min/max 范围内),都无需 JavaScript 即可实现表单校验的视觉反馈。

逻辑组合伪类

CSS 提供了四个"函数式"伪类,可以像逻辑运算一样组合其他选择器:

伪类作用
:not(s)排除匹配 s 的元素
:is(s1, s2)匹配任一 s,优先级取参数中最高者
:where(s1, s2)与 :is 相同,但优先级恒为 0
:has(s)匹配内部包含 s 的元素(父选择器)
/* 给包含图片的卡片单独加边距 —— :has 让"父选择子"成为可能 */
.card:has(img) {
  padding-bottom: 0;
}

Chapter 2 · Section 2.4

Pseudo-class Selectors


Pseudo-classes start with a colon : and describe some "state" or "structural position" of an element — a state that usually cannot be expressed directly through a class or the HTML structure, such as whether the mouse is hovering over it or whether it is the first child element.

Interaction State Pseudo-classes

Pseudo-classTrigger condition
:hoverThe mouse is hovering over the element
:activeThe instant the element is pressed
:focusThe element gains keyboard / programmatic focus
:focus-visibleOnly triggers when the focus should be presented "visibly" (e.g. keyboard Tab)
:visitedThe link has been visited
.btn:hover { background: #3f5d54; }
.btn:focus-visible { outline: 2px solid #8a5a2e; }
AccessibilityAlways keep a visible outline for :focus-visible — keyboard users rely on it to know where the focus is; removing it causes serious usability problems.

Structural Pseudo-classes

Pseudo-classMeaning
:first-childIs the first child element of its parent
:last-childIs the last child element of its parent
:only-childIs the only child element of its parent
:first-of-typeIs the first among siblings of the same tag type
:emptyHas no child nodes at all (including text)
:rootThe document root element, i.e. <html>
li:not(:last-child) {
  border-bottom: 1px solid #c9cabf;
}
Preview: every item except the last has a bottom border
Selectors
Pseudo-elements
Media queries

The nth-child Formula Explained

:nth-child(An+B) is the most powerful — and most easily confused — structural pseudo-class, where n increments from 0.

SyntaxMatched items
:nth-child(2n)The 2nd, 4th, 6th… (even)
:nth-child(2n+1)The 1st, 3rd, 5th… (odd)
:nth-child(3n)The 3rd, 6th, 9th…
:nth-child(-n+3)The first 3
:nth-last-child(1)The 1st from the end, equivalent to :last-child
/* Zebra-striped table */
tr:nth-child(even) {
  background: #e7e8e1;
}
Pitfall:nth-child counts among "all sibling elements", regardless of tag type; if you only want to count among siblings of the same type, use :nth-of-type.

Form-related Pseudo-classes

input:required { border-color: #8a5a2e; }
input:invalid  { border-color: #b3452c; }
input:checked + label { color: #3f5d54; }
input:disabled { opacity: .5; }

Other commonly used ones include :placeholder-shown (when the placeholder is visible) and :in-range / :out-of-range (whether the value is within the min/max range) — all of which provide visual validation feedback without any JavaScript.

Logical Combination Pseudo-classes

CSS provides four "functional" pseudo-classes that combine other selectors like logical operators:

Pseudo-classPurpose
:not(s)Excludes elements matching s
:is(s1, s2)Matches any s; specificity is the highest among the arguments
:where(s1, s2)Same as :is, but specificity is always 0
:has(s)Matches elements that contain s inside (the parent selector)
/* Give cards containing an image extra padding — :has makes "selecting a parent by its child" possible */
.card:has(img) {
  padding-bottom: 0;
}