CSS Podcast - 015: Pseudo-classes
假設您收到電子郵件註冊表單,且希望電子郵件表單欄位包含無效的電子郵件地址時加上紅色邊框。該怎麼做?
您可以使用 :invalid
CSS 虛擬類別,這是瀏覽器提供的許多虛擬類別之一。
虛擬類別可讓您根據狀態變更和外部因素套用樣式。也就是說,您的設計可以回應使用者輸入內容,例如無效的電子郵件地址。選取器模組會說明這些內容,本單元將詳細說明。
您可以在上一個模組中進一步瞭解虛擬元素,而虛擬元素會掛接至特定元素可能所在的特定狀態,而非該元素的一般樣式。
互動狀態
由於使用者與網頁互動,系統套用了下列虛擬類別。
:hover
如果使用者擁有滑鼠或觸控板等指標裝置,並放置在元素上方,您可以使用 :hover
掛載至該狀態,藉此套用樣式。這個方法非常實用,可以提示元素能進行互動。
:active
在點擊發生前,元素主動互動 (例如點擊),就會觸發這個狀態。如果使用��鼠這類指標裝置,這個狀態就是點擊開始且尚未釋放。
:focus
、:focus-within
和:focus-visible
如果元素可以接收焦點 (例如 <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
:target
虛擬類別會選取具備 id
與網址片段相符的元素。假設您擁有下列 HTML:
<article id="content">
…
</article>
當網址包含 #content
時,您可以將樣式附加至該元素。
#content:target {
background: yellow;
}
這對於醒目顯示可能透過略過連結明確連結的區域 (例如網站上的主要內容) 很有幫助。
歷史狀態
:link
如果 <a>
元素包含「尚未」造訪 href
值,則 :link
虛擬類別可套用於任何 <a>
元素。
:visited
您可以使用 :visited
虛擬類別,設定使用者已造訪連結的樣式。這與 :link
相反,但基於安全性考量,您可用的 CSS 屬性較少。您只能設定 color
、background-color
、border-color
、outline-color
樣式,以及 SVG fill
和 stroke
的顏色。
訂單案件
如果您定義了 :visited
樣式,則可由至少具有明確性的連結虛擬類別覆寫。因此,建議您套用 LVHA 規則來設定包含虛擬類別的連結,並依照特定順序排列::link
、:visited
、:hover
、:active
。
a:link {}
a:visited {}
a:hover {}
a:active {}
表單狀態
下列虛擬類別可以選取表單元素,前提是這些元素可能在互動期間可能處於多種狀態。
:disabled
和:enabled
如果瀏覽器停用 <button>
等表單元素,您可以使用 :disabled
虛擬類別連接到該狀態。:enabled
虛擬類別適用於相反狀態,但表單元素預設為 :enabled
,因此您可能無法發現自己達到這個虛擬類別。
:checked
和:indeterminate
如果支援的表單元素 (例如核取方塊或圓形按鈕) 處於已勾選狀態,即可使用 :checked
虛擬類別。
:checked
狀態是二進位(true 或 false) 狀態,但如果核取方塊不處於勾選或未勾選狀態,核取方塊的狀態會是進項。這就是 :indeterminate
狀態。
舉例來說,如果您使用「全選」控制項來勾選群組中所有核取方塊,便屬於這種狀態。 如果使用者隨後取消勾選其中一個核取方塊,根核取方塊將不再代表已勾選「全部」,因此應進入不確定狀態。
<progress>
元素同樣具有可設定樣式的不確定狀態。其中一種常見用途是提供條紋外觀,讓使用者知道需要更多項目。
:placeholder-shown
如果表單欄位包含 placeholder
屬性且沒有任何值,您可以使用 :placeholder-shown
虛擬類別將樣式附加到該狀態。一旦欄位中有內容 (無論是否有 placeholder
),就不再套用這個狀態。
驗證狀態
您可以使用虛擬類別 (例如 :valid
、:invalid
和 :in-range
) 回應 HTML 表單驗證。:valid
和 :invalid
虛擬類別對於成為有效欄位等情況非常有用,例如電子郵件欄位包含需比對的 pattern
。系統會向使用者顯示這個有效值狀態,協助他們瞭解可以安全地移至下一個欄位。
如果輸入包含 min
和 max
(例如數字輸入「且」值在邊界內),即可使用 :in-range
虛擬類別。
使用 HTML 表單時,您可以透過 required
屬性判斷是否為必要欄位。必填欄位將可使用 :required
虛擬類別。使用 :optional
虛擬類別可以選取不需要的欄位。
按照元素的索引、順序和出現次數選取元素
系統會產生一組虛擬類別,根據項目在文件中的位置選取項目。
:first-child
和:last-child
如要尋找第一個或最後一個項目,可以使用 :first-child
和 :last-child
。這些虛擬類別會傳回同層元素群組中第一個或最後一個元素。
:only-child
您也可以使用 :only-child
虛擬類別選取沒有同層級的元素。
:first-of-type
和:last-of-type
您可以先選取 :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
您不限於第一個和最後一個子項,且不限類型。:nth-child
和 :nth-of-type
虛擬類別可讓您指定位於特定索引的元素。CSS 選取器中的索引從 1 開始。
您可以將多個索引傳遞至這些虛擬類別。如要選取所有元素,可以使用 :nth-child(even)
。
您也可以使用 An+B 微語法建立更複雜的選取器,以定��間�����找項目。
li:nth-child(3n+3) {
background: yellow;
}
這個選取器會選取所有第三個項目,從項目 3 開始。這個運算式中的 n
是索引,從 3 開始 (3n
) 是將索引乘以多少。
假設您有 7 個 <li>
項目,因為 3n+3
會轉譯為 (3 * 0) + 3
,所以選取的第一個項目為 3。下一個疊代會選擇項目 6,因為 n
現已遞增至 1
,因此 (3 * 1) + 3)
。這個運算式適用於 :nth-child
和 :nth-of-type
。
您可以使用這個第 n 位子測試人員或這項數量選取器工具來嘗試這種選取器。
:only-of-type
最後,您可以在使用 :only-of-type
的同層級群組中找到特定類型的元素。如果您想選取只有一個項目的清單,或者想找出段落中唯一的粗體元素,這個方法就非常實用。
尋找空白元素
有時有助於找出完全空白的元素,而您也可以透過虛擬類別進行確認。
:empty
如果元素沒有子項,就會套用 :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()
如果您想找出 .post
元素中的所有 h2
、li
和 img
子項元素,您可以考慮編寫如下的選取器清單:
.post h2,
.post li,
.post img {
…
}
使用 :is()
虛擬類別,您可以編寫更精簡的版本:
.post :is(h2, li, img) {
…
}
:is
虛擬類別不僅比選取器清單更精簡,也更複雜。在大多數情況下,如果選取器清單中出現錯誤或不支援的選取器,整個選取器清單就會停止運作。如果 :is
虛擬類別中傳遞的選取器發生錯誤,系統會忽略無效的選取器,但使用有效的選取器。
:not()
您可以使用 :not()
虛擬類別排除項目。舉例來說,您可以使用該參數來設定所有沒有 class
屬性的連結樣式。
a:not([class]) {
color: blue;
}
:not
虛擬類別也有助於改善無障礙功能。舉例來說,<img>
必須有 alt
(即使值是空白值),所以您可以撰寫 CSS 規則,為無效圖片加入粗細的紅色外框:
img:not([alt]) {
outline: 10px red;
}
隨堂測驗
測驗您對虛擬類別的相關知識
虛擬類別的行為就像是將類別動態套用至元素一樣,虛擬元素則會依元素本身執行。
:
做為按鍵識別字元下列何者屬於「功能」虛擬類別?
:is()
:target
()
,表示其接受參數。:empty
()
,表示其接受參數。:not()
哪些虛擬類別是由使用者互動所產生?
:hover
:press
:squeeze
:target
:focus-within
以下何者是 <form>
狀態虛擬類別?
:enabled
:fresh
:indeterminate
:checked
:in-range
:loading
:valid