昨天我們講解了對任何屬性都能使用的屬性選擇器。
今天要繼續來介紹偽類選擇器。
偽類選擇器(Pseudo-Class),也可以譯作虛擬類別選擇器。由字面上來看,是一種依據實際上不存在的類別來挑選內容的選擇器。
這些偽類,可以理解成系統依據某些標準,默默對每個元素做的分類。就像是現實世界的人、生物或物品等,可以依據各種標準來分類一樣。
由於偽類不是我們基於分類需求,自己幫元素添加的類別(class屬性值),所以說它們是不存在的類別。
有了這些現成的偽類,就不需要再添加class屬性值做重複的分類。而且這些偽類會隨著元素狀態的變化動態調整,也可以省去手動修改屬性值的麻煩。
我們可以使用類別選擇器,依據元素的class屬性值來挑選內容;
同樣的,我們也可以使用偽類選擇器,依據元素的偽類來挑選內容。
在CSS中,以:name()
的語法表示偽類選擇器。
偽類名稱以冒號:
開頭,名稱與冒號間不能有空格;
函式型偽類選擇器在名稱後面會多加上括號,名稱與括號間同樣不能有空格。
偽類名稱跟CSS所有的關鍵字一樣,都不區分大小寫。但還是建議都用小寫,比較有一致性。
偽類選擇器跟元素選擇器、類別選擇器、ID選擇器、通用選擇器跟屬性選擇器一樣,都屬於簡單選擇器(simple selector)。[^1]
簡單選擇器可以彼此相接組成之前提過的複合選擇器。
但偽類選擇器只能接在元素選擇器或通用選擇器後面。
如果要指定是對哪一種元素做篩選,就在冒號前面加上元素選擇器,例如element:name()
;
如果沒有加上元素選擇器,就意味著是對所有種類的元素都做篩選,等同於冒號前面加上通用選擇器*:name()
,只是把通用選擇器省略掉。
偽類選擇器彼此也可以相接在一起組成複合選擇器。但有些偽類彼此的意義是互斥的,如果加在一起就篩選不出任何東西。
依據規範的定義,可以將這些偽類選擇器大致分成兩種:[^1]
Pseudo-classes are simple selectors that permit selection based on information that lies outside of the document tree or that can be awkward or impossible to express using the other simple selectors.
一種是基於文件檔案以外的資訊將元素分類與篩選(這裡先將document tree理解為文件檔案);
另一種,則是基於文件檔案本身提供的資訊將元素分類與篩選,而這種篩選難以或無法透過其他的簡單選擇器來達成。
基於上述差異可以將這些偽類選擇器進一步細分。不過Selectors Level 3跟Selectors Level 4的分類方式不同。
這裡參考Selectors Level 3的分類方式,將偽類選擇器分成六種類型:[^2]
動態偽類(Dynamic pseudo-classes)
包括:link
、:visited
等連結偽類;:hover
、:active
、:focus
等使用者操作偽類。
目標偽類(The target pseudo-class)
即:target
。
語言偽類(The language pseudo-class)
即:lang
。
UI元素狀態偽類(The UI element states pseudo-classes)
包括:enabled
、:disabled
;:checked
、:indeterminate
等。
結構偽類(Structural pseudo-classes)
包括:root
、:empty
;:first-child
、:last-child
、:first-of-type
、:last-of-type
;:nth-child()
、:nth-last-child()
、:nth-of-type()
、:nth-last-of-type()
;:only-child
、:only-of-type
等。
否定偽類 The negation pseudo-class
即:not
。
以下先介紹動態偽類。
動態偽類是依據元素名稱、屬性與內容以外,無法由文件檔案本身得到的資訊,做出的分類。
像是可以從檔案知道網頁中有什麼連結,但無法知道其中哪些連結已經點過,哪些沒有點過。還需要另外比對瀏覽記錄,才能知道每個連結的訪問狀態。
連結偽類(the link pseudo-classes)是依連結訪問狀態做出的分類。總共分成兩種互斥的狀態:
:link
,表示連結沒有訪問過。:visited
,表示連結已經訪問過。區分連結的訪問狀態並設定不同的樣式對使用者很有幫助。如果網頁中太多連結,使用者可能會忘記哪些連結還沒點過。
不過這麼做也有資安疑慮。如果掌握使用者訪問過哪些網站,可能會危及言論自由,也可能有被釣魚或詐騙的疑慮。
為免有心人士搭配腳本找出訪問過的網站,:visited
受到限制,只能用於設定顏色相關的樣式;
所有透過:link
設定的樣式,也會一併套用到已經訪問過的連結;
透過DOM查詢已訪問連結的樣式,會得到與未訪問連結相同的結果。[^3]
<a>
元素新增的內容,需要有href
屬性才會被視作連結。使用者操作偽類(the user action pseudo-classes)將元素依使用者操作狀態分成三種狀態:
:hover
:active
:focus
:active
跟:hover
是一瞬間的狀態,:focus
則是延續性的狀態。[^4]
如果是以滑鼠操作,這三種狀態會分別出現在以下時機:
:active
、:focus
狀態前,需要先:hover
。:active
、:focus
跟:hover
的狀態。:focus
的狀態會延續,直到點選其他地方。:hover
的狀態。由於這三種狀態沒有互斥,可能同時存在多個狀態。所以可以接在一起組成複合選擇器,像是a:focus:hover
。
使用者操作偽類通常會用於連結。但也可能用於表單等其他元素。
不是每個元素都能變成:active
或:focus
的狀態,這取決於文件使用的標記語言,以及瀏覽器的實作。[^2]
由於三種狀態沒有互斥,在使用偽類選擇器宣告同種屬性的樣式時需要注意順序,不然有些樣式可能會被蓋掉:[^4]
把點擊後會延續的:focus
放在最前面;
接著放滑鼠指標離開前會一直觸發的:hover
;
最後放滑鼠點擊當下才會觸發的:active
。
由於使用者操作偽類常常用於連結,如果同時以連結偽類設定同種屬性的樣式時也需要注意順序,以免樣式被蓋掉。[^3]
連結偽類是持久性的狀態,應該放在以使用者操作偽類設定的規則之前;:link
跟:visited
是互斥的狀態,彼此之間不會互相影響,順序不重要;
使用者操作偽類之間的先後順序,如同前述是:focus
、:hover
跟:active
;
於是組合起來就會是:link
、:visited
、:focus
、:hover
、:active
(被稱為LVFHA原則),
或是:visited
、:link
、:focus
、:hover
、:active
。
今天我們先介紹了什麼是偽類,還有偽類的基本語法。
可以將偽類理解為一種依據元素當下狀況自動添加、動態調整的分類。類似於class
的用途,但不需要我們自己設定屬性。
在進行這樣的分類時,除了參考檔案本身,也會參考文件檔案以外的資訊。因此可依分類依據的資訊來源將偽類做區分。
今天最後介紹的動態偽類,就是參考文件檔案以外的資訊所做的分類。
包括描述連結是否已點擊訪問的:link
、:visited
等連結偽類;
描述使用者操作狀態的:focus
、:hover
、:active
等使用者操作偽類。
至於其他偽類,因為時間差不多了,就下集待續吧~
[^1]: W3C, Selectors Level 4
[^2]: W3C, Selectors Level 3
[^3]: CSS大全,第四版。
[^4]: 黯羽轻扬, 超链接的lvha原则