昨天我們介紹了偽類的基本語法,還有動態偽類。
今天我們要繼續介紹剩下五種類型的偽類。
之前在介紹<a>
元素的時候有提過,如果網頁中的某個元素有設定id
屬性,則建立通往該網頁的連結時,在網頁原先的URL後以#
接上這個id
屬性值,連結就會通往這個元素所在的位置。
在這種通往網頁特定位置的連結中,#
後的id
屬性值又稱為片段識別符fragment identifier。其所屬、對應的元素則稱作目標元素(target element)。
透過目標偽類選擇器:target
,就可以選到URL目前指向的目標元素,對其設定樣式。
如果URL目前沒有片段識別符,或片段識別符沒有對應到任何元素(元素id
等於片段識別符),則無法透過:target
選出目標元素。
語言偽類:lang()
是依元素內容使用的語言做出的分類。
使用時在括號內填入語言縮寫,能挑選出使用指定語言的內容。
像是:lang(fr)
會找出內容使用法語的元素。
不過元素的語言偽類,除了元素的lang
屬性,還會取決於網頁的<meta>
元素,以及網路協定如HTTP等資訊。[1]
所以即使沒有特別設定元素的lang
屬性,也可以透過:lang
挑選使用特定語言的元素。
相較之下,使用屬性選擇器[attribute|="value"]
,則需要先設定元素的lang
屬性。
這種類型的偽類選擇器,將表單、按鈕等使用者介面元素,依啟用、停用等狀態分類。
:enabled
表示處於啟用狀態的元素;:disabled
表示處於停用狀態的元素。
:checked
表示已選取的單選或多選元素;:indeterminate
則表示單選或多選元素的選取狀態未定,不是已選取也不是未選取。
大多數的元素會處在既不是啟用,也不是停用的狀態。啟用與停用狀態的認定,取決於文件使用的標記語言。[1]
雖然透過CSS的display
、visibility
等屬性設定樣式,可能會讓使用者無法操作這些使用者介面元素,但這不會影響這些元素的狀態或停用狀態。
結構偽類是依據文件檔案的資訊所做的分類,而這種分類與篩選無法透過其他簡單選擇器與組合器達成。
具體來說是透過DOM樹狀模型(document tree),依據與其他節點之間的層級關係將元素分類。
:only-child
代表元素在同一層級沒有其他手足元素,是親代元素唯一的子代元素;:only-of-type
與:only-child
類似,但還會多考量元素種類。只要同一層級沒有其他相同種類的手足元素,就會符合條件。
以下舉例說明。
<article>
<p>article裡唯一的p元素</p>
<section>article裡唯一的section元素</section>
</article>
<footer>
我是文字節點
<div>footer裡唯一的元素</div>
</footer>
符合:only-child
條件的元素只有<div>
。雖然同一層級中還有文字,但文字不是元素節點,所以<div>
符合條件。<p>
跟<section>
雖然不符合:only-child
的條件,但符合:only-of-type
,因為同一層級中沒有其他同種類型的元素。
:first-child
代表的是親代元素的第一個子代元素,不論同一層級中有沒有其他手足元素;:first-of-type
則會多考量元素種類。只要同一層級中,沒有其他相同種類的手足元素排在前面,就會符合條件。
除了第一個,也有判斷是否為最後一個子代元素的偽類。
:last-child
代表的是親代元素的最後一個子代元素,不論同一層級中有沒有其他手足元素;:last-of-type
則會多考量元素種類。只要同一層級中,沒有其他相同種類的手足元素排在後面,就會符合條件。
延續前面的例子。
<article>
<p>article裡唯一的p元素</p>
<section>article裡唯一的section元素</section>
</article>
<footer>
我是文字節點
<div>footer裡唯一的元素</div>
</footer>
符合:first-child
條件的元素,除了<div>
,還有<p>
。因為只要是第一個元素就好了;<section>
雖然不符合:first-child
的條件,但仍會符合:first-of-type
。因為是<article>
裡的第一個<section>
元素。
至於:last-child
,符合條件的元素則變成<div>
跟<section>
。<p>
雖然不符合:last-child
的條件,但會符合:last-of-type
。因為是<article>
裡的最後一個<p>
元素。
:only-child
或:only-of-type
如果將:first-child
跟:last-child
組成複合選擇器,可以達成類似:only-child
的效果,即:first-child:last-child
。
同樣的:first-of-type
跟:last-of-type
也可以組成,複合選擇器,達成類似:only-of-type
的效果,即:first-of-type:last-of-type
。
這樣組合可以達成類似:only-child
或:only-of-type
的效果,優先順序也比較高。[1]
除了第一個跟最後一個,也可以選出特定順位的子代元素。
:nth-child()
是從開頭數,處在指定順位的子代元素;:nth-of-type()
類似:nth-child()
,但多考量元素種類。
:nth-last-child()
則是從結尾數,處在指定順位的子代元素;:nth-last-of-type()
類似:nth-last-child()
,但多考量元素種類。
判斷指定順位的子代元素時,同樣會省略非元素節點。
使用這些偽類時,需要在括號內以odd
、even
,或an+b
的語法來指定順位。
odd
會選出處在奇數順位的子代元素,even
會選出處在偶數順位的子代元素;
如果要指定其他順位,則需使用an+b
,以下說明它的用法。[1]
an+b
的用法運作方式:
語法上需注意:
:nth-child(2)
會選擇開頭數來第二順位的子代元素。:nth-child(2n)
類似於:nth-child(even)
,會選擇開頭數來,偶數順位的所有子代元素。:nth-child(2n+1)
或:nth-child(2n-1)
,類似於:nth-child(odd)
,會選擇開頭數來,奇數順位的所有子代元素。:nth-child(n+2)
會選擇開頭數來第二順位開始,之後的所有子代元素。:nth-child(-n+2)
會選擇開頭數來,前兩個順位的子代元素。:nth-last-child(n+2)
會選擇結尾數來第二個順位開始,之前的所有子代元素。:nth-last-child(-n+2)
會選擇結尾數來連兩個順位的子代元素,即最後兩個子代元素。:nth-child(n+2):nth-last-child(n+2)
組成的複合選擇器,會選擇開頭數來第二順位開始,與結尾數來第二順位之間,所有的子代元素。即第一個跟最後一個之外,其他所有的子代元素。:only-child
或:only-of-type
:nth-child(1)
等同:first-child
,:nth-last-child(1)
等同:last-child
。
兩者組合成複合選擇器同樣可以達成類似:only-child
的效果,即:nth-child(1):nth-last-child(1)
。
:nth-of-type(1)
等同:first-of-type
,:nth-last-of-type(1)
等同:last-of-type
。
兩者組合成複合選擇器同樣可以達成類似:only-of-type
的效果,即:nth-of-type(1):nth-last-of-type(1)
。
這樣組合可以達成類似:only-child
或:only-of-type
的效果,優先順序也比較高。[[1]]
:empty
代表沒有子代的元素。
規範有規定哪些節點算是子代:[1]
The :empty pseudo-class represents an element that has no children at all.
In terms of the document tree, only element nodes and content nodes (such as DOM [DOM-LEVEL-3-CORE] text nodes, CDATA nodes, and entity references) whose data has a non-zero length must be considered as affecting emptiness;
comments, processing instructions, and other nodes must not affect whether an element is considered empty or not.
常用的節點中,元素節點、文字節點算是子代,註解節點則不算。
所以即使元素內只有空格或換行,也無法由:empty
挑選出來。
HTML的空元素如<img>
因為無法包含內容,可以透過:empty
挑選出來。
:empty
的一個用途是,隱藏由CMS(內容管理系統)產生,但沒有實際內容的元素。[2]
:root
代表文件的根元素。
在HTML中,根元素會是<html>
元素,除非以腳本修改文件。
在其他標記語言如XML中,每種文件類型的根元素都不同。[2]
否定偽類:not()
是函式型的偽類選擇器。在括號內填入指定條件,否定偽類會挑選出不符合條件的所有元素。
括號內只能放入一個簡單選擇器,包括元素選擇器、類別選擇器、ID選擇器、通用選擇器、屬性選擇器、偽類選擇器,但不能放入另外一個否定偽類。
多個否定偽類之間可以相接組成複合選擇器。像是.link:not(li):not(p)
會挑出不是清單項目也不是段落的元素。
即使語法正確,如果條件互相衝突,否定偽類也可能沒有用,因為實際上沒有那種東西。像是:not(*)
、p:not(p)
。
今天我們介紹了其他的偽類選擇器。
包括表示網址所指元素的目標偽類;
表示元素使用語言的語言偽類;
表示元素啟用、停用等狀態的使用者介面元素偽類;
表示元素所處結構或層級關係的結構偽類;
表示與指定條件相反的元素的否定偽類。
接下來,要繼續介紹偽元素選擇器。
[1]: W3C, Selectors Level 3
[2]: CSS大全,第四版。