:`not()` 如何链接多个选择器

阅读时间 4 分钟

在 CSS 规则中,您通常会选择要应用样式的元素,所有匹配的元素都会被设置样式。您是否曾经想只对少数元素应用样式,而排除其他所有元素?这在 CSS 中是可能的,方法是使用 :not() 伪类。在这篇文章中,我们将简要介绍 CSS 伪类,:not() 伪类是如何工作的,以及当多个选择器作为参数传递时它的行为。

什么是 CSS 伪类?

在深入了解 :not() 之前,让我们快速了解一下 CSS 伪类。在 CSS 中,您使用选择器来选择要设置样式的元素。例如,您可以选择所有 <li> 元素并将 aquamarine 颜色应用到它们上面

css
/* Select and style all list items */
li {
  color: aquamarine;
}

伪类是您添加到选择器的关键字。它们允许您基于匹配类或 ID 之外的匹配条件来设置元素的样式。因此,通过使用像 :required 这样的伪类,您可以根据表单元素是否为必填项来定位它。像 :first-child 这样的伪类允许您根据元素在文档树中的位置来选择元素。您可以在 MDN Web Docs 上查看 CSS 中伪类的完整列表

一个常用的伪类示例是 :visited,它允许您为用户已访问过的链接设置样式。这也可以成为一种让用户知道他们已经点击过的链接的绝佳方式。

css
/* Select and style visited links */
a:visited {
  color: lightgreen;
}

什么是 :not() 伪类?

:not() 是否定伪类,它选择不匹配任何指定选择器的元素。因此,您可以使用 :not() 来对指定选择器排除的元素应用样式。

让我们看一个例子。假设您想选择并设置页面上所有 <code> 元素的样式,但您想排除这些元素在节标题中的情况。您可以使用 :not() 伪类来做到这一点,如下所示:

css
/* Style all code elements except those inside h2 elements */
code:not(h2 > code) {
  color: red;
}

如您所见,:not 关键字被添加到元素选择器 (<code>) 中,并且 not 选择器 (h2 > code) 被作为参数传递。

否定单个选择器

Selectors Level 3》规范仅允许将单个“简单选择器”作为 :not() 的参数。因此,您只能这样为元素设置样式:

css
:not(.item__cost) {
  font-family: "Montserrat";
}

在此示例中,所有具有 .item__cost 类的元素都将获得 Montserrat 字体。

否定多个选择器

在《Selectors Level 4》中,您可以将“复杂选择器”作为 :not() 的参数,也可以在逗号分隔的“选择器列表”中传递多个复杂选择器。这从 Chrome 88、Firefox 84 和 Safari 9 开始得到浏览器版本的支持。现在您可以这样使用 :not()

css
/* Compound selector */
input:not(:required) {
  color: #919191;
}

所有非必填的 <input> 元素将显示为深灰色。您也可以像这样传递一个逗号分隔的列表:

css
/* Compound selector */
input:not(:required, [type="button"]) {
  background-color: blue;
}

所有非必填且非按钮的 <input> 元素将具有蓝色背景。

要了解更多关于简单选择器、复合选择器、复杂选择器和选择器列表之间区别的信息,请查看 MDN Web Docs 上 CSS 选择器的选择器结构部分。

链接多个选择器

在 CSS 中,当您想将相同的样式应用于多个元素时,通常会使用逗号分隔的选择器列表来分组选择器。这在下面得到了说明:

css
h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: helvetica;
}

同样,您可以将多个 :not() 声明分组到逗号分隔的选择器列表中,以仅将指定样式应用于排除的匹配元素。结果是应用于 :not() 选择器排除的任何元素的样式。

假设我们有一个表单,我们只想设置可编辑的文本字段的样式。在下面的示例表单中,“Employed”(受雇)字段是菜单选项字段,“Employment Date”(就业日期)字段的类型是 date,“Country”(国家)字段具有 readonly 属性。这些是我们想要排除在样式之外的字段,也是我们可以通过使用 :not() 伪类来定位的字段。

这是上面表单的 HTML 代码,您可以在其中找到属性和类型

html
<form>
  <label for="name" class="name">Name:</label>
  <input type="text" id="name" name="name" value="Enter your name" />

  <label for="emp" class="emp">Employed:</label>
  <select name="emp" id="emp" disabled>
    <option selected>No</option>
    <option>Yes</option>
  </select>

  <label for="empDate">Employment Date:</label>
  <input type="date" name="empDate" id="empDate" />

  <label for="country">Country:</label>
  <input
    type="text"
    name="country"
    id="country"
    value="United States"
    readonly />

  <label for="resume">Resume:</label>
  <input type="file" name="resume" id="resume" />
</form>

可以通过使用 :not() 伪类来实现所需的样式,如下面的 CSS 所示。lightyellow 背景颜色应用于所有没有 disabled 属性 readonly 属性类型为 date<input> 元素。结果是选中并设置了“Name”(姓名)、“Employed”(受雇)和“Resume”(简历)字段的样式。请注意,即使“Employed”(受雇)字段具有 disabled 属性,它也没有被设置样式,因为它是一个 <select> 元素。

css
input:not([disabled], [readonly], [type="date"]) {
  background-color: lightyellow;
  color: red;
}

这就是 :not() 如何链接多个选择器。

总结

总结一下,在 :not() 伪类中使用逗号分隔的选择器来链接多个选择器的声明。希望这篇文章对您有所帮助。如果您有任何问题或反馈,请随时在关于这篇文章的 GitHub 讨论中贡献。您也可以在 MDN Web Docs 的Discord 服务器中加入我们打个招呼。下次再见,祝您阅读愉快,构建精彩的 Web!