虛擬類別

假設您有一個電子郵件註冊表單,且希望電子郵件表單欄位在包含無效電子郵件地址時顯示紅色邊框。該如何進行?您可以使用 :invalid CSS 擬類別,這是瀏覽器提供的眾多擬類別之一。

您可以使用擬造類別,根據狀態變更和外部因素套用樣式。也就是說,您的設計可以回應使用者輸入的內容,例如無效的電子郵件地址。這些內容會在「選取器」單元中介紹,您可以進一步瞭解這些選取器。

前一個單元中的偽元素不同,偽類別會連結至元素可能處於的特定狀態,而非該元素的一般樣式部分。

互動式狀態

下列擬似類別會在使用者與網頁互動時套用。

:hover

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 2.

Source

如果使用者有滑鼠或觸控板等指標裝置,並將其放在元素上,您可以使用 :hover 鉤住該狀態,以套用樣式。這是一種有用的提示方式,可讓使用者知道可與元素互動。

:active

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

當使用者積極與元素互動 (例如點擊) 時,系統會在點擊釋放前觸發這個狀態。如果使用滑鼠等指標裝置,則此狀態是指點擊開始時,且尚未釋放。

:focus:focus-within:focus-visible

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

如果元素可接收焦點 (例如 <button>),您可以使用 :focus 擬造類別回應該狀態。

如果元素的子項元素收到 :focus-within 的焦點,您也可以做出反應。

可聚焦的元素 (例如按鈕) 在聚焦時會顯示聚焦環,即使在點選時也是如此。在這種情況下,開發人員會套用下列 CSS:

button:focus {
    outline: none;
}

這段 CSS 會在元素獲得焦點時移除預設的瀏覽器焦點環,這會對使用鍵盤瀏覽網頁的使用者造成無障礙問題。如果沒有焦點樣式,使用者在使用 tab 鍵時,就無法追蹤焦點目前的位置。使用 :focus-visible 時,您可以在元素透過鍵盤獲得焦點時顯示焦點樣式,同時使用 outline: none 規則在指標裝置與元素互動時避免顯示焦點樣式。

button:focus {
    outline: none;
}

button:focus-visible {
    outline: 1px solid black;
}

:target

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.3.

Source

:target 擬似類別會選取具有與網址片段相符的 id 元素。假設您有以下 HTML:

<article id="content">
    …
</article>

如果網址包含 #content,您可以將樣式附加至該元素。

#content:target {
    background: yellow;
}

這項功能可用於醒目顯示可能已透過跳躍連結連結到的區域,例如網站的主要內容。

歷史狀態

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

:link 擬似類別可套用至任何 <a> 元素,只要該元素含有尚未造訪href 值。

:visited

您可以使用 :visited 擬造類別,為使用者已造訪的連結套用樣式。這是 :link 的反向狀態,但您可用的 CSS 屬性較少,原因是安全性。您只能為 colorbackground-colorborder-coloroutline-color 和 SVG fillstroke 的顏色設定樣式。

順序很重要

如果您定義 :visited 樣式,則可由至少具有相同特異性的連結虛擬類別覆寫。因此,建議您使用 LVHA 規則,以特定順序為含有擬造類別的連結設定樣式::link:visited:hover:active

a:link {}
a:visited {}
a:hover {}
a:active {}

表單狀態

下列擬似類別可選取表單元素,並在這些元素與使用者互動時,顯示這些元素的各種狀態。

:disabled:enabled

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

如果瀏覽器停用表單元素 (例如 <button>),您可以使用 :disabled 疑似類別鉤掛該狀態。:enabled 擬似類別可用於相反的狀態,但表單元素預設為 :enabled,因此您可能不會使用這個擬似類別。

:checked:indeterminate

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

當支援的表單元素 (例如核取方塊或圓形按鈕) 處於勾選狀態時,即可使用 :checked 擬造類別。

:checked 狀態是二進位(true 或 false) 狀態,但核取方塊在未勾選或取消勾選時,確實有介於兩者之間的狀態。這就是所謂的 :indeterminate 狀態。

舉例來說,如果您有「選取全部」控制項,會勾選群組中的所有核取方塊,就會出現這種狀態。如果使用者隨後取消勾選其中一個核取方塊,根核取方塊就不會再代表勾選「全部」,因此應置於未定狀態。

<progress> 元素也有可設定樣式的不確定狀態。常見的用途是將其顯示為條紋狀,以表示目前無法確定需要多少。

:placeholder-shown

Browser Support

  • Chrome: 47.
  • Edge: 79.
  • Firefox: 51.
  • Safari: 9.

Source

如果表單欄位具有 placeholder 屬性和沒有值,您可以使用 :placeholder-shown 擬造類別,將樣式套用至該狀態。只要欄位中含有內容 (無論是否含有 placeholder),系統就不會再套用此狀態。

驗證狀態

Browser Support

  • Chrome: 10.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 5.

Source

您可以使用疑似類別回應 HTML 表單驗證,例如 :valid:invalid:in-range:valid:invalid 擬似類別適用於電子郵件欄位等情境,因為這些欄位含有需要比對的 pattern,才能成為有效欄位。您可以向使用者顯示這個有效值狀態,協助他們瞭解可以安全地移至下一個欄位。

如果輸入內容含有 minmax (例如數值輸入內容),:in-range 擬類別就會可用,且值會在這些範圍內。

在 HTML 表單中,您可以使用 required 屬性判斷欄位是否為必填欄位。:required 擬似類別可用於必填欄位。您可以使用 :optional 擬似類別選取非必要欄位。

依索引、順序和出現次數選取元素

有一系列的擬似類別,可根據項目在文件中的所在位置選取項目。

:first-child:last-child

Browser Support

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 3.
  • Safari: 3.1.

Source

如要找出第一或最後一個項目,可以使用 :first-child:last-child。這些擬似類別會傳回一組同層元素中的第一個或最後一個元素。

:only-child

Browser Support

  • Chrome: 2.
  • Edge: 12.
  • Firefox: 1.5.
  • Safari: 3.1.

Source

您也可以使用 :only-child 擬造類別,選取沒有同層元素的元素。

:first-of-type:last-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

您可以選取 :first-of-type:last-of-type,這些元素一開始看起來似乎與 :first-child:last-child 執行相同的操作,但請考慮以下 HTML:

<div class="my-parent">
    <p>A paragraph</p>
    <div>A div</div>
    <div>Another div</div>
</div>

以及以下 CSS:

.my-parent div:first-child {
    color: red;
}

由於第一個子項是段落而非 div,因此不會有任何元素顯示紅色。:first-of-type 擬似類別在這種情況下非常實用。

.my-parent div:first-of-type {
    color: red;
}

雖然第一個 <div> 是第二個子項,但仍是 .my-parent 元素中的第一個類型,因此根據這項規則,會以紅色標示。

:nth-child:nth-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

您也不必侷限於第一個和最後一個子項和類型。:nth-child:nth-of-type 虛擬類別可讓您指定特定索引的元素。CSS 選取器中的索引從 1 開始。

您也可以將索引以外的值傳遞至這些擬類別。如要選取所有偶數元素,可以使用 :nth-child(even)

您也可以使用 An+B 微語法,建立更複雜的選取器,以便在固定間隔找到項目。

li:nth-child(3n+3) {
    background: yellow;
}

這個選取器會從第 3 個項目開始,選取每隔一個項目。這個運算式中的 n 是從 0 開始的索引,而 3 (3n) 則是該索引的乘數。

假設您有 7 個 <li> 項目。系統會選取 3 這個項目,因為 3n+3 會轉譯為 (3 * 0) + 3。下一個疊代作業會選取項目 6,因為 n 現已遞增至 1,因此為 (3 * 1) + 3)。這個運算式適用於 :nth-child:nth-of-type

您可以使用這個第 n 個子項測試器或這個數量選取器工具,試驗這類選取器。

:only-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

最後,您可以使用 :only-of-type 在同層元素中找出某種類型元素。如果你想選取只有一個項目的清單,或是想找出段落中唯一的粗體元素,這項功能就非常實用。

尋找空白元素

有時您可能需要辨識完全空白的元素,這時也可以使用偽類別。

:empty

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

如果元素沒有子項,則會套用 :empty 擬似類別。不過,子項不只是 HTML 元素或文字節點,也可以是空白,因此在偵錯下列 HTML 時,如果想知道為何無法使用 :empty,可能會感到困惑:

<div>
</div>

原因是開頭和結尾 <div> 之間有空白,因此空白無法運作。

如果您對 HTML 的控制權不大,且想隱藏空白元素 (例如 WYSIWYG 內容編輯器),:empty 擬類別就很實用。編輯者在此處新增了一個空白段落。

<article class="post">
 <p>Donec ullamcorper nulla non metus auctor fringilla.</p>
 <p></p>
 <p>Curabitur blandit tempus porttitor.</p>
</article>

您可以使用 :empty 找到並隱藏該檔案。

.post :empty {
    display: none;
}

尋找及排除多個元素

部分擬似類別可協助您編寫更精簡的 CSS。

:is()

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 78.
  • Safari: 14.

Source

如果您想在 .post 元素中尋找所有 h2liimg 子元素,建議您編寫類似以下的選擇器清單:

.post h2,
.post li,
.post img {
    
}

您可以使用 :is() 擬類別,編寫更精簡的版本:

.post :is(h2, li, img) {
    
}

:is 擬群組別不僅比選取器清單更精簡,也更寬容。在大多數情況下,如果選取器清單中出現錯誤或不支援的選取器,整個選取器清單就會停止運作。如果 :is 擬類別中傳遞的選取器發生錯誤,系統會忽略無效的選取器,但會使用有效的選取器。

:not()

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

您也可以使用 :not() 擬類別排除項目。舉例來說,您可以使用它為所有沒有 class 屬性的連結套用樣式。

a:not([class]) {
    color: blue;
}

:not 擬類別也可以協助您改善無障礙存取功能。舉例來說,<img> 必須有 alt,即使是空值也一樣,因此您可以編寫 CSS 規則,為無效圖片加上粗紅色輪廓:

img:not([alt]) {
    outline: 10px red;
}

進行隨堂測驗

測驗您對擬類別的瞭解

虛擬類別會以類別已動態套用至元素的方式運作,而虛擬元素則會對元素本身運作。

以下何者為功能性擬類別?

:is()
:not()
:empty
:target

下列哪個疑似類別是由於使用者互動而產生?

:hover
:target
:press
:focus-within
:squeeze

下列何者為 <form> 狀態的擬造類別?

:enabled
:valid
:indeterminate
:in-range
:fresh
:loading
:checked