選擇某類的最後一個元素——CSS3僞類選擇器走過的坑

衆所周知,在CSS3規範中,添加了許多了僞類選擇器,這些選擇器代替了很多JS的工做,讓咱們從之前經過獲取DOM節點進而進行樣式修改的操做,變得更加便捷高效。 然而我在近期開發使用的過程當中,遇到了很多坑,事實證實認真閱讀文檔仍是頗有必要的,因此這裏總結分享幾個我遇到的問題,經過一個需求對幾對選擇器作解析,但願對你們也有所幫助。html

需求: 尋找頁面上某類名的首個或最後一個元素。bash

:first-child / :last-child

CSS3手冊中描述:學習

  • :first-child:選擇屬於其父元素的首個子元素的每一個子元素
  • :last-child:選擇屬於其父元素的最後一個子元素的每一個子元素

這個描述難免讓人看起有些雲裏霧裏,因此咱們直接來看個例子:spa

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    p:first-child {
      border: 1px solid red;
    }
    p:last-child {
      border: 1px solid blue;
    }
  </style>
</head>
<body>
  <div>
    <p>這是第一個段落。</p>
    <p>這是第二個段落。</p>
    <p>這是第三個段落。</p>
  </div>
  <div>
    <p>這是第一個段落。</p>
    <p>這是第二個段落。</p>
    <p>這是第三個段落。</p>
  </div>
</body>
</html>
複製代碼

結果:3d

因而可知,:first-child和:last-child選擇器會將頁面中全部元素裏,符合父元素下首個或末尾個指定類型的子元素選出來。 這麼看來,這個選擇器彷佛不難理解,那麼這個選擇器能夠解決咱們的需求嗎?讓我看看下面這個場景:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    .p:first-child {
      border: 1px solid red;
    }
    .p:last-child {
      border: 1px solid blue;
    }
  </style>
</head>
<body>
  <div>
    <p class="p">這是第一個段落。</p>
    <p class="p">這是第二個段落。</p>
    <p class="p">這是第三個段落。</p>
  </div>
  <div>
    <p>這是一個干擾段落。</p>
    <p class="p">這是第一個段落。</p>
    <p class="p">這是第二個段落。</p>
    <p class="p">這是第三個段落。</p>
    <p>這是一個干擾段落。</p>
  </div>
</body>
</html>
複製代碼

結果:code

在這個例子裏,咱們發現第二個部分並無實現咱們想要的效果,這是爲何呢?原來:first-child和:last-child選擇器並無咱們想的那麼智能,他所能作的,只是找到父元素下的第一個或最後一個元素,而當咱們想經過這個選擇器找到具體某一類的首個和最後一個元素時,當且僅當元素同時知足這兩個條件纔會被選中,因此總結一下: 想要經過這組選擇器選擇某一類型首個或最後一個元素須要知足

  • 該元素屬於這個類名
  • 該元素是其父元素下的首個或最後一個子元素

:first-of-type / :last-of-type

有了對上面兩個選擇器的進一步認知後,再來看看這一對。cdn

CSS3手冊中描述:htm

  • :first-of-type:選擇屬於其父元素的首個指定類型子元素的每一個子元素
  • :last-of-type:選擇屬於其父元素的最後一個指定類型子元素的每一個子元素

來看個例子:blog

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    p:first-of-type {
      border: 1px solid red;
    }
    p:last-of-type {
      border: 1px solid blue;
    }
  </style>
</head>
<body>
  <div>
    <p>這是第一個段落。</p>
    <p>這是第二個段落。</p>
    <p>這是第三個段落。</p>
  </div>
  <div>
    <p>這是第一個段落。</p>
    <p>這是第二個段落。</p>
    <p>這是第三個段落。</p>
  </div>
</body>
</html>
複製代碼

結果:開發

乍看之下,這對選擇器彷佛與上一對差很少,那咱們來看看下面這個場景:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    .p:first-of-type {
      border: 1px solid red;
    }
    .p:last-of-type {
      border: 1px solid blue;
    }
  </style>
</head>
<body>
  <div>
    <div>這是一個干擾段落。</div>
    <p class="p">這是第一個段落。</p>
    <p class="p">這是第二個段落。</p>
    <p class="p">這是第三個段落。</p>
    <div>這是一個干擾段落。</div>
  </div>
  <div>
    <p>這是一個干擾段落。</p>
    <p class="p">這是第一個段落。</p>
    <p class="p">這是第二個段落。</p>
    <p class="p">這是第三個段落。</p>
    <p>這是一個干擾段落。</p>
  </div>
</body>
</html>
複製代碼

結果:

在第一部分裏,咱們發現,當父元素含有其餘標籤類型的元素時,咱們仍是成功的選中了指定類型的元素,可當父元素裏其餘兄弟組件標籤類型和咱們指定的元素相同時,咱們依舊沒有辦法選中首個和最後一個元素,這又是爲何呢?這就要說到:first-of-type和:last-of-type的工做原理

  • 找到指定類型的元素的標籤類型
  • 尋找其父元素下符合該標籤類型的元素
  • 當且僅當元素符合選擇器中指定類型,且是父元素下同類標籤中首個或最後一個子元素時,方可被選中

:nth-child(n) / :nth-last-child(n)

CSS3手冊中描述:

  • :nth-child(n):選擇屬於其父元素的第n個子元素,不論元素的類型
  • :nth-last-child(n):選擇屬於其父元素的倒數第n個子元素,不論元素的類型

經過描述其實咱們也不難看出,當n爲1的時候,其實現的結果和咱們第一組介紹的:first-child / :last-child同樣,因此簡單將n設爲1對咱們解決咱們的需求並無什麼幫助,那你確定要問,爲何還要介紹這一對選擇器。 實際上經過上面兩組選擇器,咱們也發現了,當咱們的應用場景是一個存在多個相同標籤類型子元素的容器下,選擇其中某一類名的首個或最後一個元素是十分困難的事情,但假若咱們知道在想要的類先後有多少個相同標籤的元素,咱們能夠採用一種委曲求全的方法,來看下面這個例子。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    .p:nth-child(2) {
      border: 1px solid red;
    }
    .p:nth-last-child(2) {
      border: 1px solid blue;
    }
  </style>
</head>
<body>
  <div>
    <p>這是一個干擾段落。</p>
    <p class="p">這是第一個段落。</p>
    <p class="p">這是第二個段落。</p>
    <p class="p">這是第三個段落。</p>
    <p>這是一個干擾段落。</p>
  </div>
</body>
</html>
複製代碼

結果:

如此,咱們終於實現了咱們的需求,固然你也可使用:nth-of-type(n)和:nth-last-of-type(n),在有了上面的基礎後,相信你們理解也不難,這裏就再也不贅述。

總結

最後咱們來總結一下,在解決這個需求的時候,其實咱們遇到了幾種不一樣的場景,針對不一樣的場景,咱們須要使用不一樣的選擇器。

  • 當父元素下只有指定的類型:使用:first-child / :last-child
  • 當父元素下除了指定類型外,還有其餘標籤元素:使用:first-of-type / :last-of-type
  • 當父元素下除了指定類型(某一類名)外,還有其餘同類標籤元素,且已知其餘標籤個數:使用:nth-child(n) / :nth-last-child(n)或:nth-of-type(n) / :nth-last-of-type(n)

從上,咱們也看出還有一種場景,也就是,當父元素下除了指定類型(某一類名)外,還有其餘同類標籤元素,其餘標籤個數未知的狀況,這種場景,我目前想不到用CSS找到他的好辦法,歡迎你們補充。

雖然這只是CSS3中很小的一部分,可是學習知識不只要追求廣度,也要追求深度,與你們共勉。

相關文章
相關標籤/搜索