:`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!