iT邦幫忙

2025 iThome 鐵人賽

DAY 22
0
Modern Web

前端迷走中:從零開始的新手之路系列 第 22

[Day 22] 選擇不障礙,讓CSS幫你──偽類選擇器 下

  • 分享至 

  • xImage
  •  

昨天我們介紹了偽類的基本語法,還有動態偽類。

今天我們要繼續介紹剩下五種類型的偽類。

目標偽類

之前在介紹<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屬性。

UI元素狀態偽類

這種類型的偽類選擇器,將表單、按鈕等使用者介面元素,依啟用、停用等狀態分類。

:enabled表示處於啟用狀態的元素;
:disabled表示處於停用狀態的元素。

:checked表示已選取的單選或多選元素;
:indeterminate則表示單選或多選元素的選取狀態未定,不是已選取也不是未選取。

大多數的元素會處在既不是啟用,也不是停用的狀態。啟用與停用狀態的認定,取決於文件使用的標記語言。[1]

雖然透過CSS的displayvisibility等屬性設定樣式,可能會讓使用者無法操作這些使用者介面元素,但這不會影響這些元素的狀態或停用狀態。

結構偽類

結構偽類是依據文件檔案的資訊所做的分類,而這種分類與篩選無法透過其他簡單選擇器與組合器達成。

具體來說是透過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(),但多考量元素種類。

判斷指定順位的子代元素時,同樣會省略非元素節點。

使用這些偽類時,需要在括號內以oddeven,或an+b的語法來指定順位。

odd會選出處在奇數順位的子代元素,even會選出處在偶數順位的子代元素;
如果要指定其他順位,則需使用an+b,以下說明它的用法。[1]

an+b的用法

運作方式:

  • n會依序代入0或其他正整數。
  • a為負數時,只有an+b為正數時才有對應的元素。
  • a跟b都為0時,沒有對應的元素。

語法上需注意:

  • a跟b必須是整數,可以是正數、負數或0。
  • b為負數時,必須省略前面的+。
  • 可以省略部分的情況有:
    • 如果a為1,可以省略1,只寫為n+b。
    • 如果a為0,可以省略an,除非b已經被省略;
      如果省略an,則b為非負數時可以省略前面的+;
      如果b為0,也可以省略+b,除非an已經被省略。
  • 可以加上空格的情況有:
    • an+b跟括號間可以有空格。
    • a跟n之間不能空格。
    • 如果an跟b都存在,+/-前後可以加上空格;
      如果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大全,第四版。


上一篇
[Day 21] 選擇不障礙,讓CSS幫你──偽類選擇器 上
下一篇
[Day 23] 選擇不障礙,讓CSS幫你──偽元素選擇器
系列文
前端迷走中:從零開始的新手之路23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言