iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 27
5
Modern Web

金魚都能懂的 CSS 選取器 - 金魚都能懂了你還怕學不會嗎系列 第 27

:nth-of-type() & :nth-last-of-type() - 你覺得燒腦但其實根本不燒腦的選取器趴兔

總算...金魚都能懂的 CSS 選取器 講了20幾篇,總算可以講到這個大家都很有興趣的 :nth-of-type 選取器了,看到這邊又要再再再老話一句了 ( 夠了你! ),再次的重複一下, of-type主要看的是分類順序,所以不管你寫在:nth-of-type 前面的是甚麼,他都只認分類順序喔,所以有了這樣的概念後,我們就可以開始來了解了( 好眼熟的一句話,Amos 你是複製貼上吼! )。

:nth-of-type:first-of-type還有:last-of-type 一樣的概念,基本上這種選取器會先將你網頁中的物件依標籤來做分類,分類之後再來做同類的順序選取,而 :nth-of-type 的選取語法與 :nth-child 可以說是完全一樣,包含其括號內的數學公式也都是完全相同的,純粹就只有選取到的物件會有差異而已,為了第一次看此文章的朋友,我將 :nth-child 的文章 修改一下,換成 :nth-of-type 的型態來看看。

選取奇數與偶數

:nth-of-type() 用白話文來說的話,基本上就是 選取第 n 的同類子物件,而這個 n 就是我們要給予的條件,也就是我們要選取到的目標物,這個 n 可以是公式也可以使用關鍵字,我們就先來看 oddeven 這兩個關鍵字,我們可以在括號內使用關鍵字 odd 來選取奇數物件,而其中最重要的一點,也是程式設計師比較容易卡腦的地方就是,起始值是 1,讓我們用範例簡單來看一下吧。

HTML

<div class="wrap">
	<span>span 1</span>
	<div>div 1</div>
	<span>span 2</span>
	<div>div 2</div>
	<span class="A">span 3 有 class A</span>
	<div class="A">div 3 有 class A</div>
	<span class="A">span 4 有 class A</span>
	<div class="A">div 4 有 class A</div>
</div>

CSS

.wrap *{
  display: block;
  padding: 5px 10px;
  margin: 2px;
}
.wrap :nth-of-type(odd){
	background-color: red;
}

上面這段例子各位可以狠狠的點擊這邊看畫面,可以看到的結果會是 span 與 div 的 1、3 ... 這幾個奇數物件被選取到了,當然如果你是程式設計師的話,應該會卡一下,畢竟各位都是選索引值,所以就請各位程式設計師忍耐並轉腦消化一下了。

按照上面這個邏輯,那麼我們使用關鍵字 even 的話就是選取偶數囉,不多說馬上來看一下範例的 CSS 原始碼

.wrap :nth-of-type(even){
	background-color: red;
}

上面這段例子各位依舊可以狠狠的點擊這邊看畫面,可以看到結果就是 2、4...這幾個排序為偶數的物件被選取到了,這樣大家應該有比較理解了吧。

選取特定單一物件

有了前面的例子後,我們就能來看選取特定單一物件的方式,我們只需要將想要選取的那個物件的排序數字寫進括號內即可,例如我想要選取的是第2個物件,那我就寫 :nth-of-type(2){ ...略 } 即可。如果這麼容易理解你還要看例子的話...自己不會寫喔! (兇屁!) ㄟ不對! 我這邊寫好了,你可以狠狠的點擊這邊看畫面

那麼這樣可能會有朋友就會突發奇想了,想問看看是否有簡單的方式可以讓我選取到第 5 個跟第 6 個? 然後就會有新手開始自己發明語法規則了,千萬別這樣自己亂寫啊,那只是浪費你的生命、時間以及肝指數啊! 比較簡單的方式大概就是寫兩個選取器並且使用群組式宣告了,像是下方這樣

.wrap :nth-of-type(5),
.wrap :nth-of-type(6){
	background-color: red;
}

如果你覺得上面這樣的寫法有損你的程度的話,那麼我們也可以用比較裝逼的方式,一行搞定來選,像是下面這樣的語法

.wrap :nth-of-type(n+5):nth-of-type(-n+6){
	background-color: red;
}

上面這樣的選取方式等於是順便講解了 選取特定區間物件 的方式,你可以狠狠的點擊這邊看畫面

間隔跳位選取物件

一開始我們講到了公式,事實上 :nth-of-type 最棒且最強大的地方就在於他的公式選取了,就跟 :nth-child 一樣啦,但 :nth-of-type 是選取同類物件,例如我們可以每隔三個同類物件就選取,這很像是迴圈在做的事情對吧! 不多說先看效果先

<div class="wrap">
	<span>span 1</span>
	<div>div 1</div>
	<span>span 2</span>
	<div>div 2</div>
	<span class="A">span 3 有 class A</span>
	<div class="A">div 3 有 class A</div>
	<span class="A">span 4 有 class A</span>
	<div class="A">div 4 有 class A</div>
	<span>span 5</span>
	<div>div 5</div>
	<span>span 6</span>
	<div>div 6</div>
	<span class="A">span 7 有 class A</span>
	<div class="A">div 7 有 class A</div>
	<span class="A">span 8 有 class A</span>
	<div class="A">div 8 有 class A</div>
</div>
.wrap {
	width: 500px;
	margin: 100px auto;
	border: 1px solid #000;
}
.wrap *{
  display: block;
  padding: 5px 10px;
  margin: 2px;
}
.wrap :nth-of-type(3n){
	background-color: red;
}

你可以點擊這邊看畫面,結果就是瀏覽器會先將 wrap 內的物件分類,然後再將每個同類物件裡面的第三個選取,如果你要第4個裡面的第4個被選取到的話,那就是直接在括號內寫 4n,是不是非常的簡單呢。

間隔選取原理 (與 :nth-child 相同,讀過 :nth-child 的可跳過)

在上個例子中我們可以利用簡單的公式達到間隔選取的目的,但原理到底是甚麼? 讓我們來看一下數學公式吧! 不!!! 別折磨我了,我自小家境清寒數學不好(謎:兩者有何關聯?),好不容易長大脫離數學的魔掌了,現在又要回去看公式,哪招啦?!別害怕! 我們只需要知道四則運算中的三個「加/減/乘」就夠了,這都是我們平日就在用的數學運算喔。

公式分解前段

括號內的公式an+b由四個項目組成,其中 ab 是可以自訂的數值,而 + 則是可變更的運算符號 ( 運算子 ),至於 n 則是一個固定且不不可更改由 0 開始的遞增數列。

除了上述的公式分解外,此外我們又可以把公式拆成兩大部分,an 指的是 a 乘 n 的意思,所以綜合上面一開始所講的 n 所代表的意義,我們就能像下面這樣來解釋

3n 指的是 3 乘 n,而 n 是個由0開始的固定數列 ( 就是 0 1 2 3 4 5 6 7 8 9...n),我們就可以得到下列結果清單

  • 3 x 0 = 0
  • 3 x 1 = 3
  • 3 x 2 = 6
  • 3 x 3 = 9
  • 3 x 4 = 12
  • 以此類推繼續計算下去

上面清單中最右側的 0、3、6、9、12 就是我們得到的結果,也就是會被選取到的物件順序了,所以 :nth-of-type(3n) 可以讓我們選取到第3個、第6個、第9個、第12個...不斷選下去直到你愛上我直到沒有可選取的物件為止。

公式分解後段

上面講述了公式前段的原理,接下來來看公式an+b後段的 +b 的部分,其中 + 號是可以被變更為 - 號,也就是跟前段公式搭配起來之後,要取得的計算結果,所以假如前段是 3n 後段是 +1 的話,我們就能夠取得以下結果清單

  • 3 x 0 + 1 = 1
  • 3 x 1 + 1 = 4
  • 3 x 2 + 1 = 7
  • 3 x 3 + 1 = 10
  • 3 x 4 + 1 = 13
  • 以此類推繼續計算下去

如果我們把 + 號改成 - 號的話,:nth-of-type(3n-1) 就能得到以下清單。

  • 3 x 0 - 1 = -1
  • 3 x 1 - 1 = 2
  • 3 x 2 - 1 = 5
  • 3 x 3 - 1 = 8
  • 3 x 4 - 1 = 11
  • 以此類推繼續計算下去

公式變化

看完公式的分析之後,這時候我們就能進一步的來看公式可以怎樣的變化,在公式中我們可以運用 ab 兩值的賦值與否來增加變化,所以就會有以下幾種公式變化

  • an+b
  • an-b
  • n+b
  • n-b
  • an
  • -an+b

上面這一堆公式很有趣眼花吧,千萬不要被這一堆公式嚇到了,而眼尖的你應該會發現最後一個公式沒講過的樣子,其實不是沒講過,只是 Amos 沒有提到 a 也可以是負值罷了。

事實上這一堆公式中,還能繼續分析下去,但是為了節省時間,我們還是先把比較常用的提出來就好,實際上我們在專案中比較常用到的大概就是 an+b 比較多,所以真的別被這一堆公式嚇到閃尿了,放心!

實際應用與計算技巧

在多數的專案中,我們比較常用到的大概就是奇數 ( odd )、偶數 ( even ) 及倍數 ( an ) 這三個項目的選取,像是 3n 其實就是 3 的倍數,4n 就是 4 的倍數,就這麼簡單,要增加變化的則是多一個 倍數中的特定數 這個項目,如果說我們要選取到 3 個裡面的第 2 個項目的話,我們就能夠直接寫 3n+2,如果我們要選取到 3 個裡面的第 1 個的話,我們就寫 3n+1,根本連算都不用算啊,一眼就能看出來我要選哪個啦。

文章頁面前言的應用

為了讓各位更加清楚 :nth-of-type 這個選取器的特性,就讓我們用文章內頁來看看這個選取方式吧,以下 HTML 是一個常見到的文章內頁的格式

<article>
	<h1>
		<a href="">金魚都懂的這個網頁畫面怎麼切</a>
	</h1>
	<p>「<a href="https://www.youtube.com/playlist?list=PLqivELodHt3hxeuLX8PYaI8u1GcDaBoJo">金魚都能懂的這個網頁怎麼切</a>」是 IThome 鐵人賽的主題,也是一個實用且完整的免費教學影片,主要訴求在簡單快速將一個網頁畫面完成,但也由於時間有限,所以沒有處理RWD部分,留給廣大網友腦補囉。</p>
	<p>金魚都懂的這個網頁畫面怎麼切,基本上是基於「<a href="https://www.youtube.com/playlist?list=PLqivELodHt3iL9PgGHg0_EF86FwdiqCre">金魚都懂的網頁設計入門</a>」所開發的新的金魚系列教學影片,內容雖然是走實戰部分,但由於還是針對新手所開發的教學內容,所以難度依舊走簡單上手來規劃,對新手算是親和力高的一個切版實戰教學影片</p>
	<p>金魚教學系列的出發點就在於讓新手也能快速了解各種必備的網頁入門知識,所以為了針對一些新手對 CSS 選取器不熟的困擾,Amos 又再次規劃了「<a href="https://ithelp.ithome.com.tw/users/20112550/ironman/2799">金魚都能懂的 CSS 選取器 系列</a>」讓新手能夠一次看完一些必學的 CSS 選取器,金魚教學系列不僅免費以外,Amos 還有直播「<a href="https://www.youtube.com/playlist?list=PLqivELodHt3igUDMZVPK_Z5rLbhSg1ZvB">大師常來聊</a>」系列影,內容是針對新手與老手都適宜的方向所規劃,節目中安排了一些業界大師來分享不同主題,並提供觀眾與講者之間的互動與解惑,同樣! 免費!!!</p>
	<p>如何快速獲得這些免費資訊? 最簡單的方式就是訂閱 CSScoke 的頻道,切記除了訂閱以外,旁邊有一顆小鈴鐺也要按下,這樣才會在第一時間收到 Amos 的影片上架通知與直播通知喔。重點是!!!訂閱依舊免費!!</p>
	<p>本文是配合<a href="https://ithelp.ithome.com.tw/articles/10227242">此教學文章</a>使用的範例,但內容文字所提的都是真實的呦。</p>
</article>

如果我希望讓他第一個段落當作前言,並且讓他能夠有突顯的效果,那我的 CSS 可以這樣寫

article p:nth-of-type(1){
	font-size: 20px;
	padding: 1em;
	border: 1px solid #aaa;
}

上面例子各位可以狠狠的點擊這邊來看畫面喔。

對了! 有沒有發現我用的例子很像是直接使用 :first-of-type 就能做到了呢? 實際上 :nth-child():nth-of-type() 兩者在很多情境上面都同樣適用,除非真的有很特殊的狀況啦,不然兩者使用起來差異不會太大,導致很多開發者會有點無所適從,但只要搞懂 childof-type 的特性差異其實就不難選擇了,而且這範例中 Amos 還特別在 :nth-of-type 的左側添加了 p 來限定僅選取到 p 標籤,如果不添加 p 會出現甚麼結果呢? 歡迎各位在下方留言告訴 Amos 喔^^

還有還有~我是不是忘了講 :nth-last-of-type() 是做甚麼的了? 恩......簡單來說,跟 :first-of-type 以及 :last-of-type 一樣,:nth-of-type 是從前面開始選,而 :nth-last-of-type 是從結尾開始選,就這樣的差別而已,這應該不需要特地花時間解釋了吧^^

以上就是今天的 金魚都能懂的 CSS 選取器 - :nth-of-type,如果文中描述有誤歡迎各位前輩不吝指正,各位金魚我們明天見~

金魚都能懂的教學系列

鐵人雙主題挑戰中,歡迎訂閱一波

金魚都能懂的這個網頁畫面怎麼切

立刻訂閱 CSS可樂的網站/頻道享受精彩文章

Line搜尋「@CSScoke」加入CSS可樂公開帳號,可以收到 Amos 第一手資訊喔
CSS 可樂部落格
CSS coke 的 Youtube 直播頻道
快按此訂閱 CSS coke 的頻道接收最新教學
/images/emoticon/emoticon12.gif


上一篇
:nth-child() & :nth-last-child() - 你覺得燒腦但其實根本不燒腦的選取器
下一篇
:disabled & :enabled 表單用僞類選取器 - 一眼看穿那些不能按的按鈕
系列文
金魚都能懂的 CSS 選取器 - 金魚都能懂了你還怕學不會嗎30

2 則留言

0
mimicats
iT邦新手 5 級 ‧ 2019-11-21 10:55:38

如果不添加 p 會出現甚麼結果呢?

Amos, 我測試後的結果是全部第一組的 a 連結 都變成有框和背景的物件了, 不知對不對呀!! QQ"

CSScoke iT邦新手 4 級‧ 2019-11-23 13:05:00 檢舉

哪個選取器?

article p:nth-of-type(1){...} 這邊喔, 如果把p拿掉的話 就變成第一組的 a 元素,都變成有框和背景...(我測試的結果是這樣)

CSScoke iT邦新手 4 級‧ 2019-12-05 10:00:26 檢舉

把p 拿掉的話,就變成article 內全部的第一個物件會被選取到,所以包含p 或 a 都會被選到

0
阿展展展
iT邦研究生 1 級 ‧ 2019-12-05 09:16:37

第三個 lover
第六個 lover
第九個 lover
第...

有人站在你身後她非常火 /images/emoticon/emoticon31.gif

CSScoke iT邦新手 4 級‧ 2019-12-05 10:04:01 檢舉

/images/emoticon/emoticon04.gif/images/emoticon/emoticon04.gif/images/emoticon/emoticon04.gif

我要留言

立即登入留言