网站

CSS 伪类

伪类 | MDN

引入

网页中的元素按照 HTML 的层级结构组成一棵树,父元素、子元素、兄弟元素之间有明确的关系。

有时候我们需要根据元素在这棵树中的位置来选中它们,例如”选中列表的第一项”、“选中父元素的最后一个子元素”、“选中某个类型的第三个元素”。

CSS 树结构伪类就是用来根据元素在文档树中的位置选中元素的。

正文

定义

定义

CSS 树结构伪类通过元素在文档树中的父子关系位置关系来选中元素,例如第一个子元素、最后一个子元素、第 n 个子元素等。

树结构伪类不关心元素的状态或用户的操作,只关心元素在 HTML 结构中的位置。

常见树结构伪类

:root

选中文档根元素,在 HTML 中通常是 <html> 元素。

:root {
  --main-color: #2563eb;
  --font-size: 16px;
}

:root 常用于声明全局 CSS 变量,因为它的优先级高于 html 选择器。

:empty

选中没有任何子节点的元素,包括文本节点和空格。

div:empty {
  display: none;
}

这条规则会隐藏所有内容为空的 <div> 元素。

注意:<div></div> 是空的,但 <div> </div>(包含空格)不是空的。

:first-child

选中父元素的第一个子元素

li:first-child {
  font-weight: bold;
}

这条规则会让每个列表的第一项显示为粗体。

:last-child

选中父元素的最后一个子元素

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

这条规则会移除列表最后一项的底部边框。

:only-child

选中父元素的唯一子元素,也就是没有兄弟元素的元素。

p:only-child {
  margin: 0;
}

这条规则会移除作为父元素唯一子元素的段落的外边距。

:nth-child(n)

选中父元素的第 n 个子元素

/* 选中第 3 个子元素 */
li:nth-child(3) {
  color: red;
}
 
/* 选中所有偶数位置的子元素 */
li:nth-child(even) {
  background-color: #f5f5f5;
}
 
/* 选中所有奇数位置的子元素 */
li:nth-child(odd) {
  background-color: white;
}
 
/* 选中从第 3 个开始的所有子元素 */
li:nth-child(n+3) {
  opacity: 0.8;
}

:nth-child(n) 的参数可以是数字、evenodd,或者公式(例如 2n3n+1)。

:nth-last-child(n)

选中从后往前数第 n 个子元素

/* 选中倒数第 2 个子元素 */
li:nth-last-child(2) {
  color: blue;
}

:nth-child() 类似,但是从后往前数。

:first-of-type

选中父元素中同类型的第一个元素

p:first-of-type {
  font-size: 18px;
}

这条规则会让父元素中的第一个 <p> 元素字体变大,即使前面还有其他类型的元素。

:last-of-type

选中父元素中同类型的最后一个元素

p:last-of-type {
  margin-bottom: 0;
}

这条规则会移除父元素中最后一个 <p> 元素的底部外边距。

:only-of-type

选中父元素中同类型的唯一元素

img:only-of-type {
  display: block;
  margin: 0 auto;
}

如果父元素中只有一个 <img> 元素,这条规则会让它居中显示。

:nth-of-type(n)

选中父元素中同类型的第 n 个元素

/* 选中同类型的第 2 个元素 */
p:nth-of-type(2) {
  color: green;
}
 
/* 选中同类型的所有偶数位置元素 */
div:nth-of-type(even) {
  background-color: #f0f0f0;
}

:nth-child() 类似,但只计算同类型的元素。

:nth-last-of-type(n)

选中父元素中同类型的倒数第 n 个元素

/* 选中同类型的倒数第 1 个元素 */
p:nth-last-of-type(1) {
  font-style: italic;
}

例子

列表斑马纹效果

<ul>
  <li>第一项</li>
  <li>第二项</li>
  <li>第三项</li>
  <li>第四项</li>
  <li>第五项</li>
</ul>
li:nth-child(odd) {
  background-color: #f9fafb;
}
 
li:nth-child(even) {
  background-color: white;
}

这个例子让列表的奇数项和偶数项显示不同背景色,形成斑马纹效果,提高可读性。

移除第一项和最后一项的边距

.card:first-child {
  margin-top: 0;
}
 
.card:last-child {
  margin-bottom: 0;
}

这个例子移除第一张卡片的顶部外边距和最后一张卡片的底部外边距,避免容器出现多余的空白。

高亮特定位置的元素

<section>
  <h2>标题</h2>
  <p>第一段</p>
  <p>第二段</p>
  <p>第三段</p>
</section>
/* 选中第一个段落 */
p:first-of-type {
  font-size: 18px;
  color: #2563eb;
}
 
/* 选中最后一个段落 */
p:last-of-type {
  margin-bottom: 0;
}

这个例子让第一段文字变大并显示蓝色,同时移除最后一段的底部外边距。

特点

  • :first-child / :last-child / :only-child 根据元素在父元素中的位置选中
  • :nth-child(n) / :nth-last-child(n) 可以选中特定位置或按规律选中多个元素
  • :first-of-type / :last-of-type / :only-of-type 只计算同类型的元素
  • :nth-of-type(n) / :nth-last-of-type(n) 在同类型元素中按位置选中
  • :root 选中文档根元素,常用于声明全局变量
  • :empty 选中没有任何内容的元素
  • 树结构伪类不受元素状态影响,只和 HTML 结构有关

注意事项

  • :first-child:first-of-type 不同:前者要求是第一个子元素,后者只要求是同类型的第一个
  • :nth-child() 计数时包括所有类型的子元素,:nth-of-type() 只计算同类型的元素
  • :empty 对空格和换行符敏感,<div></div> 是空的,但 <div> </div> 不是
  • :nth-child() 的参数从 1 开始计数,不是从 0 开始
  • even 表示偶数,odd 表示奇数
  • 公式 2n 表示所有偶数位置,2n+1 表示所有奇数位置
  • 某些复杂的 :nth-child() 公式可能影响性能,尽量使用简单的表达式

理解

可以把树结构伪类理解为”位置定位器”。

它让 CSS 能够根据元素在 HTML 树状结构中的位置关系选中元素,例如”我是第一个”、“我是最后一个”、“我是第三个”、“我是唯一的一个”。

这样做的好处是不需要给每个元素添加额外的 class,就能根据它们的位置应用不同的样式。

例如,列表的第一项可能需要特殊样式,最后一项可能不需要底部边框,偶数项和奇数项可能需要不同背景色。用树结构伪类可以很方便地实现这些效果。

树结构伪类的核心价值是根据 HTML 结构自动应用样式,让代码更简洁,也更容易维护。

引出

理解了树结构伪类之后,可以继续学习:

也可以学习 CSS 变量,配合 :root 实现全局样式管理。