CSS3 nth 伪类选择器
考察下面的 HTML 代碼片段:
<div><section>section 1</section><section>section 2</section><ul><li>item 1</li><li><ul><li>sub item 1</li><li>sub item 2</li><li>sub item 3</li></ul></li><li>item 3</li><li>item 4</li><li>item 5</li><li>item 6</li><li>item 7</li><li>item 8</li><li>item 9</li></ul><section>section 3</section><section>section 4</section><section>section 5</section> </div>單憑 section 可以讓我們選中所有的<section> 標(biāo)簽,what if we wanna specific ones? 譬如只選中第一個(gè)。
那你可能已經(jīng)知道:first-child偽類(lèi)選擇器了,所以選中第一個(gè)也不是什么麻煩事情。類(lèi)似地可以用:last-child選中最后一個(gè)指定的元素。
section:first-child,section:last-child {color: red; }here comes out the result:
當(dāng)場(chǎng)景再?gòu)?fù)雜一些的時(shí)候,譬如選中第2個(gè),第3個(gè),第基數(shù)個(gè),很自然地,我們會(huì)想到引入一個(gè)變量來(lái)完成任務(wù)。
nth 系列榮譽(yù)登場(chǎng)
CSS3中的 nth 系列選擇器便是這樣一種支持變量計(jì)算的選擇器,可以完成上述復(fù)雜的選擇需求。
譬如高亮前面示例 HTML 片段中第基數(shù)個(gè) section 和 li 標(biāo)簽可以這樣做:
section:nth-child(2n+1),li:nth-child(2n+1){color:red; }and here comes out the result again:
:nth-child完整的語(yǔ)法為:nth-child(an+b),它匹配父容器下面中第an+b個(gè)子元素。例如:nth-child(3n+1)將會(huì)選中位置位于第1(3*0+1),4(3*1+1),7(3*2+1)...的元素。
像:nth-child這樣厲害的選擇器還有3個(gè)!它們分別是:
- :nth-last-child(an+b) 原理同:nth-child,只不過(guò)方向相反,從滿足條件的兄弟子節(jié)點(diǎn)后面開(kāi)始計(jì)數(shù)
- :nth-of-type(an+b) 匹配第 an+b 個(gè)相同標(biāo)簽的元素
- :nth-last-of-type(an+b) 同 nth-of-type ,只不過(guò)方向相反,從最后開(kāi)始計(jì)數(shù)。
借助于這樣靈活的選擇器,在編寫(xiě)樣式時(shí)使我們更加得心應(yīng)手,甚至有了很多花樣玩法。
:nth-child
:nth-child(an+b) 會(huì)匹配所有兄弟節(jié)點(diǎn)中位置位于an+b位置的元素。 其中 n 是從0開(kāi)始的正整數(shù)。
除了像前面所說(shuō)的可以通過(guò)完整的表達(dá)式匹配到連續(xù)規(guī)律位置的元素外,如果我們將 a 設(shè)為0的話,就可以匹配指定的單個(gè)元素。
譬如考察下面的 HTML 片段:
<div><p>foo</p><p>bar</p><p>baz</p> </div>高亮第二個(gè)元素:
p:nth-child(2){color: red; }同理,:nth-child(3) 會(huì)選中第三個(gè)元素。
這個(gè)示例中,也可以用:nth-last-child:
p:nth-last-child(2){color: red; }效果當(dāng)然是一樣的,因?yàn)?nth-last-child(2)從后面開(kāi)始數(shù)第二個(gè),正好與順位數(shù)第二個(gè)是同一元素。
:nth-of-type
:nth-of-type(an+b)用法上沒(méi)有區(qū)別,但它只會(huì)匹配相同標(biāo)簽的兄弟元素。也就是在:nth-child的基礎(chǔ)上加了一條限制:標(biāo)簽要一致。
還是考察剛剛的 HTML 片段,我們要選中第二個(gè)<p> 標(biāo)簽,仍然是指定位置為2即可:
p:nth-of-type(2){color: red; }但情況變一下,我們?cè)诘?個(gè)<p>標(biāo)簽前面加上另外一個(gè)元素譬如<section>,考察更新后的 HTML 片段:
<div><p>foo</p><section>quz</section><p>bar</p><p>baz</p> </div>此時(shí)我們?nèi)匀幌胍x中第2個(gè)<p>標(biāo)簽。
p:nth-child(2){color: red;/*會(huì)匹配失敗,因?yàn)榈诙€(gè)子元素不是 p 標(biāo)簽*/ } p:nth-of-type(2){color: red;/*仍然匹配成功*/ }此時(shí)用:nth-child(2)不會(huì)選中任何元素,因?yàn)樗囊馑际沁x中div下面子元素中的第2個(gè)元素,并且這個(gè)元素是一個(gè)<p> 標(biāo)簽。而上面 HTML 片段中,第二個(gè)子元素明顯不是<p>標(biāo)簽,所以匹配失敗。
而通過(guò):nth-of-type(2)來(lái)選擇則仍然生效。因?yàn)椴还艿?個(gè)<p>元素前面插幾個(gè)<section>標(biāo)簽,此時(shí)內(nèi)容為bar的<p>標(biāo)簽仍然是父容器所有子節(jié)點(diǎn)中順位第二個(gè)類(lèi)型為<p>的標(biāo)簽。
:nth-child與:nth-of-type的區(qū)別
通過(guò)前面的示例可以看出,:nth-of-type在你始終需要選擇第 N 個(gè)特定類(lèi)型的元素時(shí)更為可靠,它首先會(huì)提取出所限定的元素類(lèi)型,然后再?gòu)倪@個(gè)沒(méi)有雜質(zhì)的集合中去匹配順序。
因此:nth-of-type在大多數(shù)時(shí)候可能更滿足你的需要,畢竟很多時(shí)候需求是選中第3個(gè)<span>,第5個(gè)<p>。而不是第7個(gè)元素,無(wú)論是什么類(lèi)型的節(jié)點(diǎn)。
這里有一個(gè)頁(yè)面:nth Tester可以方便地把玩 nth 系列的四大金鋼。通過(guò)可視化操作應(yīng)該能夠更好地理解。
擴(kuò)展的花樣玩法
前面說(shuō)道,表達(dá)式an+b可以將 a 取值為0,這樣就可以選中第 b 個(gè)元素。如果將 a 取值為1的話,我們就可以選中從第 b 個(gè)元素開(kāi)始的所有元素。
譬如選中從第三個(gè)元素開(kāi)始的所有<p>標(biāo)簽:
<div><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p> </div> p:nth-child(n+3){color: red; }雖然 n 是從0開(kāi)始的正整數(shù),但 a 其實(shí)可以取負(fù)值的。當(dāng)我們將 a 取值為-1的時(shí)候,可以達(dá)到只選取前 b 個(gè)元素的目的。
示例:選中前3個(gè)元素
<div><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p> </div> p:nth-child(-n+3){color: red; }另外,選取基數(shù)和偶數(shù)元素時(shí),可以通過(guò)指定值為odd與even來(lái)完成,這和2n+1與2n效果是一樣的。
css 選偶數(shù)元素 p:nth-child(2n){ color: red; } /*或者*/ p:nth-child(even){ color: red; }
css 選基數(shù)元素 p:nth-child(2n+1){ color: red; } /*或者*/ p:nth-child(odd){ color: red; }
https://css-tricks.com/useful-nth-child-recipies/
需要注意的地方
與 class 的搭配
博主在使用過(guò)程中剛好遇到一個(gè)問(wèn)題,可以拿出來(lái)分享一下。
那就是 nth 系列對(duì)元素的類(lèi)名是不生效的,也就是說(shuō)它只對(duì)標(biāo)簽名起作用,如果你使用時(shí)指定為 class 名則不會(huì)生效。
譬如考察下面的 HTML 片段與 CSS:
<div><p>1</p><p class="foo">2</p><p class="foo">3</p><p class="foo">4</p><p class="foo">5</p> </div> /*從帶 class 為'foo'的 p 標(biāo)簽中選取第2個(gè)將字體設(shè)為紅色*/ p.foo:nth-of-type(2){color: red; } /*從帶 class 為'foo'的 p 標(biāo)簽中選取第3個(gè)將字體設(shè)為綠色*/ p.foo:nth-child(3){color: green; }上述 CSS 中,我們只希望對(duì)帶 class 且值為foo的<p>標(biāo)簽進(jìn)行操作,于是使用了類(lèi)選擇器進(jìn)行限制,但最終結(jié)果其實(shí)是這樣的:
我們預(yù)期值為3的應(yīng)該為紅色,因?yàn)樗菐?class 且值為foo這種類(lèi)型里面的第二個(gè),但其實(shí)值為2的 <p>標(biāo)簽被選中了。因?yàn)榈谝粋€(gè)不帶 class 的 <p> 標(biāo)簽其實(shí)也參與了進(jìn)來(lái),證明 class 選擇器其實(shí)沒(méi)有生效,并沒(méi)有起到限制的作用。
對(duì)于:nth-child同理。
推而廣之,其實(shí)對(duì)于其他嵌套 CSS 語(yǔ)法組合(arbitrary selector),譬如屬性選擇[type=text],:nth-child,:nth-of-type 都是會(huì)忽略的。
對(duì)于:nth-child,納入考量的永遠(yuǎn)是同屬同一個(gè)父容器下同一級(jí)所有的兄弟元素。而對(duì)于:nth-of-type來(lái)說(shuō),則是同一父容器下,同一級(jí)所有兄弟元素中標(biāo)簽類(lèi)型相同的元素。
與 querySelector 的搭配
既然是偽類(lèi)選擇器,所以就無(wú)法使用 querySelector 來(lái)進(jìn)行選擇。我想你已經(jīng)讀出另外一層意思,即所有偽類(lèi)選擇器在 querySelector 中都不起作用,而不只是 nth 系列。原因見(jiàn)W3C Spec。
瀏覽器兼容性
拿 :nth-child 為例,nth 系列的瀏覽器支持情況還是蠻理想的。可以放心使用。
更多資料
- MDN :nth-child doc
- MDN :nth-of-type doc
- :nth Tester
- The Difference Between :nth-child and :nth-of-type
- Useful :nth-child Recipes
- nth-child doesn't respond to class
- Can I combine :nth-child() or :nth-of-type() with an arbitrary selector
總結(jié)
以上是生活随笔為你收集整理的CSS3 nth 伪类选择器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: error PRJ0003 : 生成“c
- 下一篇: CSS 基本样式