「重新認識 CSS」這個系列名稱的由來就如其名,我想要重新認識它。雖然以前就有學過 CSS,但這次想從 CSS Spec 中學到最原始的定義和內容,更加了解 CSS 的原理,讓我在切版的時候可以更加確定自己在做什麼,我踩到的雷只是因為我不夠了解它才會炸開。
在這 30 天的內容中,會將 Spec 內看到的資料整理成這個系列,也希望正在學 CSS 的各位可以更加了解它。另外我也會同時將文章發至我的 Blog,如果想直接看文內的程式碼 Demo 畫面,可以到我的 Blog 來看。
本文同步發表於 Titangene Blog:重新認識 CSS - Pseudo-class (偽類) (2)
「重新認識 CSS」系列文章發文於:
之前有提到以下這些都是 simple selector:
本篇會介紹 pseudo-class,如果想了解其他 simple selector 可參閱之前介紹的「重新認識 CSS - Simple Selector & Groups of selector」。
如之前所說,pseudo-class 是以 :
為開頭,後面接著 pseudo-class 的名稱,有些會在後面加上括號 ()
,並在括號之間加上值。例如::nth-child(2)
。
注意:
- pseudo-class 和 pseudo-element 不相同
- pseudo-class 是以
:
為開頭- pseudo-element 是以
::
為開頭,但也可以以:
為開頭,因為在舊版的 W3C Spec 中沒有將 pseudo-class 和 pseudo-element 區分成:
和::
。如果你寫 pseudo-element 是用:
,大部份瀏覽器也還是會支援這種語法。
當使用 structural pseudo-class 時,它會計算各 sibling 元素的位置:
:root
pseudo-class:root
pseudo-class 代表文件的 root 元素:root
pseudo-class 與 Document
物件的 root 元素會 match<html>
元素此 pseudo-class 會根據 inclusive sibling 之間的 index 來選擇元素。
選擇 index 為多少的 sibling (兄弟,同層) 元素,元素的第一個子元素的 index 是 1。
只有開頭為 nth
的 Child-indexed Pseudo-classes 和 Typed Child-indexed Pseudo-classes 都可以在 ()
括號裡面可以使用下面這幾種值:
an + b
:
n
可以是任何正整數或 0 的數值a
和 b
的值必須是整數 (正數、負數或 0)a
和 b
都大於 0 時,可以更好的將 sibling 元素劃分為元素群組 (groups of a elements),並選擇每個群組的第 b
個元素, 例如:
3n + 1
可以 match 到第 1、4、7...等子元素0n + 5
等同於 5
a
為負值,且 n >= 0
時,只有 an + b
為正值才可以代表 document tree 中的元素odd
:奇數的所有 sibling 元素,等同於 2n + 1
even
偶數的所有 sibling 元素,等同於 2n
語法詳情可參閱 Selectors Level 3 的「6.6.5.2. :nth-child() pseudo-class」章節部份。
Child-indexed Pseudo-classes 有下面這些 selector:
:nth-child(an+b)
:
:nth-last-child(an+b)
:
:first-child()
:
:nth-child(1)
:last-child()
:
:nth-last-child(1)
:only-child()
:
:first-child:last-child
或 :nth-child(1):nth-last-child(1)
,但 specificity 較低此 pseudo-class 類似於 Child Index Pseudo-classes,但此 pseudo-class 是基於 sibling 列表中相同 type (tag 名稱) 的元素之間的元素 index 來解析。
Typed Child-indexed Pseudo-classes 有下面這些 selector:
:nth-of-type(an+b)
:
:nth-last-of-type(an+b)
:first-of-type()
:nth-of-type(1)
:last-of-type()
:nth-last-of-type(1)
:only-of-type()
:first-of-type:last-of-type
或 :nth-of-type(1):nth-last-of-type(1)
,但 specificity 較低:nth-of-type()
與 :nth-child()
的差異下面是 :nth-of-type()
和 :nth-child()
的範例:
<ul>
<li>1 (1 li)</li>
<li>2 (2 li)</li>
<div>3 (div)</div>
<li>4 (3 li)
<ul class="nested-list">
<li>4-1</li>
<li>4-2</li>
<li>4-3</li>
<li>4-4</li>
<li>4-5</li>
</ul>
</li>
<li>5 (4 li)</li>
<li>6 (5 li)</li>
</ul>
<ul>
<li>1 (1 li)</li>
<li>2 (2 li)</li>
<div>3 (div)</div>
<li>4 (3 li)</li>
<li>5 (4 li)</li>
<li>6 (5 li)</li>
</ul>
div { color: olive; }
li:nth-of-type(odd) {
margin: 2px;
outline: 2px solid red;
}
li:nth-child(odd) {
border: 2px solid blue;
}
這個範例有兩個 ul
元素,裡面各有五個 li
元素,而且在與第二個 li
元素同層的後面加上一個 div
元素,這是用來驗證 :nth-of-type()
和 :nth-child()
的差異用的。另外,在第一個 ul
元素裡面還有一個巢狀 <ul class="nested-list">
元素,它放在第四個 li
元素裡面,這是用來巢狀的元素也可以被 selector 選到。
每個元素的前面都有一個編號,代表在 sibling 元素之間的 index。而後面的括號是用來告訴你它是 li
元素還是 div
元素,如果是 li
元素就會註記是第幾個 li
元素。例如:4 (3 li)
就代表是第四個 sibling 元素,並且是第三個 li
元素。
可以看到那些有紅色 outline
的元素都有 match 到 li:nth-of-type(odd)
,因為此 pseudo-class 是以 of-type
為結尾,所以此 selector 只會找相同 type 的 sibling 元素 (OS:就很像是忽略了 div
元素的存在)。只要是奇數的 sibling 元素都會被選起來,套用紅色的 outline 樣式。
而那些有藍色 border
的元素都有 match 到 li:nth-child(odd)
,因為此 pseudo-class 是以 child
為結尾,所以此 selector 會直接找是 li
的 sibling 元素,並且要是奇數的 sibling 元素。不過,第三個 sibling 元素是 div
元素,不是 li
元素,因此 li:nth-child(odd)
就不會 match 到此 div
元素
而巢狀 <ul class="nested-list">
元素裡面只有五個 li
元素,沒有其他 type 的元素,所以都會選到奇數的 sibling 元素 (因為沒有亂路的元素)。
Demo:Codepen 連結
:not(X)
是一個函數符號,可將一個 simple selector (不包括 :not(X)
本身) 作為參數。:not(X)
代表不選擇 match 到 X
simple selector 的元素。
註:以下這些都是 simple selector:
- type selector:例如
div
- universal selector:例如
*
- attribute selector:例如
div[foo]
- class selector:例如
.myclass
- ID selector:例如
#myid
- pseudo-class:例如
a:hover
不能巢狀使用,所以 :not(:not(...))
是無效的。另外請注意,因為 pseudo-element 不是 simple selector,所以 pseudo-element 不是 :not()
的有效參數。
例如:match HTML 文件中所有未被禁用的 button
元素:
button:not([disable])
註:
[disable]
是 attribute selector,詳情請參閱我前幾天寫的「重新認識 CSS - Attribute selector (屬性選擇器)」。
match 除了 #titan
元素之外的所有元素:
*:not(#titan)
註:
#titan
是 ID selector,詳情請參閱我前幾天寫的「重新認識 CSS - Simple Selector & Groups of selector」。
今天介紹一些 structural pseudo-class,接下來幾天會接續介紹其他 selector。
資料來源: