发布于 2026-01-06 1 阅读
0

适用于常见场景的高级 CSS 选择器

适用于常见场景的高级 CSS 选择器

作者:安德鲁·斯宾塞✏️

CSS 很奇特。它与 Web 开发人员使用的任何其他语言都截然不同,但它对网站的视觉呈现(即用户与之交互的部分)至关重要。CSS 最基本的用法很简单。例如,`{{ background-color }}`background-color: red表示背景颜色为红色。然而,任何参与过大型 CSS 代码库开发的人都会告诉你,它很快就会变得非常复杂且令人困惑。

CSS GridBEMDart、Sass ……CSS 的知识浩如烟海,总有新东西需要学习,让人应接不暇!与其关注那些新特性,不如让我们聚焦于 CSS 的一个基本构建模块——选择器。更好地理解选择器及其高级用法,就能用更少的代码和更简洁的 CSS 解决常见问题。

什么是选择器?

我们先来确认一下理解是否一致。CSS选择器用于告诉浏览器要将属性应用到哪个元素上。选择器可以是通用的,可以应用于一大类元素;也可以是更具体的,只应用于单个 HTML 元素。选择器共有五种类型

  • 用于选择 HTML 片段的简单选择器,例如div<code> #id<div></code>、<code><span></code> 或 <code><div></code>。.class
  • 基于代码关系(例如“子项”p > div或“相邻兄弟项”)的组合器选择器div + div
  • 伪类选择器用于选择元素的特定状态:hover,例如`true`、:first-child`false` 或 `false`。:nth-of-type
  • 伪元素选择器用于选择元素的特定部分,例如`<div>` ::after::selection`<span>` 或 ` <span> ::first-letter`。请注意,这些选择器始终使用双冒号表示法,::而伪类选择器则使用单冒号。
  • 属性选择器用于选择具有特定属性的元素,例如([class|="class-name"],,[type="text"]或)。[target]

如果使用两个不同的选择器来声明同一个元素的样式,则更具体的那个选择器会生效——无论它们在 CSS 文件中的顺序如何。例如,像 `<class>` 这样的类选择器.class-name比像 `<element>` 这样的通用 HTML 元素选择器更具体span。如果您需要复习一下浏览器如何决定应用哪些 CSS 样式(也称为CSS 层叠),请尝试这个小测验。

现在我们已经了解了选择器是什么,接下来让我们深入探讨如何有效地使用它们。你可以利用一些不太常用的选择器,甚至可以将它们组合起来,从而减少所需的代码量!以下是我在 CSS 中使用的一些更高级的选择器。

LogRocket 免费试用横幅

:nth-last-child(-n + 2)

CSS 伪类选择器有很多种,可以用来从一组相关元素(或父元素的子元素)中选择一个元素。

<parent>
    <child></child>
    <child></child>
</parent>
Enter fullscreen mode Exit fullscreen mode

还有 ` :first-child\n`、 `\n` :nth-child:nth-of-type`\n` 等等,不胜枚举n。当这些选择器被转换成使用数字、计数器、`\n`odd或 `\n`的表达式时,它们会变得更加强大even。你可以使用数学运算来选择组中几乎任意数量的元素。例如,`\n`n是一种创建代数表达式的方法。因此, (2n+4)`\n` 等价于(2*n)+4`\n`,它将选择从第四个元素开始的每隔一个元素:

(2*0)+4 = 4
(2*1)+4 = 6
(2*2)+4 = 8
(2*4)+4 = 10
Enter fullscreen mode Exit fullscreen mode

这在很多情况下都很有用。例如,你是否曾经需要只设置列表中最后两项的样式?你可以给这两个元素添加一个类,但这会产生更多的 HTML 和 CSS 代码,或者你可以使用一个 CSS 选择器,像这样:

.item:nth-last-child(-n+2)
Enter fullscreen mode Exit fullscreen mode

你可以把这个选择器理解为“选择元素的最后两个子元素.item”。观察它的工作原理,首先-n+2选择倒数(-0+2)=2第二个元素,然后选择(-1+2)=1最后一个元素,接着选择空元素,以此类推,直到选择完所有子元素。之所以只选择两个元素,是因为选择器前面的负号使其从左到右递减。如果你想选择最后三个元素,只需使用 `--select` 即可。这样我们就可以在不修改任何 HTML 代码的情况下选择这些元素!(-2+2)=0(-3+2=-1)n-n+3

:not(:last-child)

以最后一个例子为例,你可以结合:last-child使用:not选择器。这在处理组中最后一个元素样式不同的场景时非常有用。网站经常需要显示项目列表,项目之间留有一定的间距。这类场景中常见的问题是需要移除组中最后一个项目下方的间距。

选择器演示

在使用 CSS 时,我们常常会习惯性地先为最常见的场景设置样式,然后再用更具体的选择器来处理一些特殊情况。这样,更具体的选择器的样式就会覆盖更通用选择器的样式。在我们的例子中,最终效果可能如下所示:

.image {
  margin-bottom: 2rem;

  &:last-child {
    margin-bottom: 0;
  }
}
Enter fullscreen mode Exit fullscreen mode

或者,您可能使用BEM CSS 结构向 HTML 中添加了一个全新的类。这将导致如下结果:

.image {
  margin-bottom: 2rem;
}

.image--last {
  margin-bottom: 0;
}
Enter fullscreen mode Exit fullscreen mode

两种方法最终都会得到七行代码和一个覆盖属性。虽然不算糟糕,但如果你把 CSS 看作一种编程语言,并将逻辑直接“编程”到选择器中,就可以将 CSS 简化为以下形式:

.image:not(:last-child) {
  margin-bottom: 2rem;
}
Enter fullscreen mode Exit fullscreen mode

阅读上面的选择器,它的意思是“选择不是最后一个子元素的图片”。三行代码,没有覆盖任何样式——不错!

元素:悬停 + 相邻兄弟元素

我们来看另一个场景——悬停状态。有时你需要调整的元素与悬停的元素不同。在 JavaScript 中,这相当简单,因为 JavaScript 可以轻松地查找特定元素(也称为遍历 DOM)。不过,通常情况下,只要 HTML 结构正确,你只需要 CSS 即可。

使用 CSS,你可以使用诸如 `<div> ` 或 ` <span>` 之类的组合选择器来定位不同的元素。但 CSS 无法做到的是定位鼠标悬停元素的父元素。下图展示了 CSS 可以定位的元素:.parent > .child.element + .general-sibling

<div>
  <a>
    The element that is hovered
    <span>This is a child, CSS can style this</span>
  </a>
  <span>This is a sibling, CSS can style this</span>
  The "parent" <div> cannot be styled with CSS when the <a> is hovered
</div>
Enter fullscreen mode Exit fullscreen mode

如何使用强大的兄弟元素选择器?如果您有两个兄弟元素,并且需要设置第二个元素的悬停状态样式,您可以这样做:

兄弟选择器也可以用于表单字段。使用label:hover + input选择器,<label>可以与元素交互,从而突出显示<input>位于其后的兄弟元素<label>

轮到你了

下次当你觉得 CSS 是一种低人一等的语言时,不妨再想想。它只是……与众不同而已。而这种不同之处,可能会让你感到沮丧,也可能会让你受益匪浅,这取决于你的角度。在你放弃 CSS,转而添加更多 HTML 代码或用 JavaScript 把一切都搞砸之前,不妨先了解一下 CSS 选择器和属性。很可能其中就包含你需要的选项。


你的前端是否占用了用户的 CPU 资源?

随着 Web 前端变得越来越复杂,资源消耗型功能也对浏览器提出了越来越高的要求。如果您希望监控和跟踪生产环境中所有用户的客户端 CPU 使用率、内存使用率等信息,不妨试试 LogRocket。

替代文字

LogRocket就像 Web 应用的 DVR,记录 Web 应用或网站中发生的一切。您无需猜测问题原因,即可汇总并报告关键的前端性能指标,回放用户会话及应用状态,记录网络请求,并自动显示所有错误。

革新 Web 应用调试方式——立即开始免费监控。


这篇文章《常见场景的高级 CSS 选择器》最初发表于LogRocket 博客

文章来源:https://dev.to/bnevilleoneill/advanced-css-selectors-for-common-scenarios-3gl6