CSS 中的偽元素和偽類

已發表: 2020-08-20

每次我們必須修改 Web 上的 CSS 樣式時,Toni 和我都會玩剪刀石頭布,看看誰是能夠完成這項任務的“幸運兒”。 你可能會問,怎麼會? 好吧,很長一段時間以來,使用 HTML 和 CSS 一直是一種痛苦,因為一方面修復某些東西會破壞其他地方的很多東西。

漫畫 gif 顯示 CSS 有多複雜
人們不禁對前端開發人員所做的工作感到欽佩和驚嘆。

但事實上,近年來 CSS 發生了很大變化,如果您利用它的新功能,正確有效地佈局和設置您的網站樣式會容易得多。 在我看來,我們最近看到的 CSS 的兩個重大進步是包含,首先是flex (用於佈局行和列),然後是grid (用於佈局網格)。

CSS 充滿了可以簡化工作的特性。 今天我們將看到其中的兩個:偽元素和偽選擇器。

如何使用 CSS 偽元素“創建內容”

CSS 偽元素是一種訪問在 DOM 中沒有關聯節點的 HTML 部分的機制。 例如,“我們文檔的一部分”可能是“段落的第一行”、“段落的第一個字母”或“用戶所做的選擇”,它們都沒有關聯的節點​​。 但是偽元素也是一種通過 CSS在現有元素之前或之後創建內容的方法。

CSS3 中可用的偽元素有:

  • ::before : 在元素之前添加內容
  • ::afte after r:在元素之後添加內容
  • ::first-letter :選擇“block”元素的第一個字母(即display屬性設置為blockinline-blocktable-cell等的那些)
  • ::first-line : 選擇“塊”元素的第一行
  • ::selection :指訪問者選擇的文檔部分

如您所見,偽元素的特點是以一對冒號 ( :: :) 開頭。 這就是您使用它們的方式。

選擇文檔的部分

例如,假設我們希望某個段落的第一行為橙色並帶有下劃線。 好吧,只需執行以下操作:

 p::first-line { color: orange; text-decoration: underline; }

你會得到正確的結果:

Lorem ipsum dolor sit amet, consectetur adipiscing elit。 Vestibulum mollis leo in turpis interdum,pharetra velit elementum。 Nam eget lacus sed lacus dictum scelerisque。 Proin porta ligula sed mi semper, vel interdum massa auctor。 Pellentesque et massa congue,tincidunt erat ac,tincidunt elit。 Sed ac dolor metus。 Nam commodo metus sed ligula consectetur interdum。 Curabitur odio est, tempor id egestas nec, aliquam at nisl。

另一方面,如果您想修改選擇,方法完全相同。 請記住,我們可以調整的 CSS 屬性數量僅限於colorbackgroundcursoroutline

 p::selection { background: #21acde; color: white; }

假設您選擇了某些內容,您可以在以下段落中看到結果:

Lorem ipsum dolor sit amet, consectetur adipiscing elit。 Vestibulum mollis leo in turpis interdum,pharetra velit elementum。 Nam eget lacus sed lacus dictum scelerisque。 Proin porta ligula sed mi semper, vel interdum massa auctor。 Pellentesque et massa congue,tincidunt erat ac,tincidunt elit。 Sed ac dolor metus。 Nam commodo metus sed ligula consectetur interdum。 Curabitur odio est, tempor id egestas nec, aliquam at nisl。

創建新內容

您還可以選擇將內容動態添加到您的頁面。 例如,假設您有一個這樣的項目列表:

 <ul> <li>One</li> <li>Two</li> <li>Three</li> </ul>

通常,列表是這樣的:

但是您可以對其進行調整,以便使用藍條將每個元素與下一個元素分開:

在列表中的每個項目上使用::after偽元素,如下所示:

 ul li { display: inline; } ul li::after { color: #21acde; content: " | "; display: inline-block; }

使用::before::after偽元素,您可以做很多很棒的事情。 例如,您可以在單個元素中組合多個背景、在打印頁面時顯示鏈接的 URL、對浮動元素進行排序、標籤塊、美化排版等等。

如何使用偽類更精確地應用樣式

CSS 偽類允許我們選擇我們網站的元素,這些元素要么處於特定狀態,要么具有使它們分開的一些特殊屬性。 最常見(也是最古老)的示例可能是鏈接偽類:

  • a:link是那些你還沒有訪問過的鏈接
  • a:visited是您已經訪問過的任何鏈接
  • a:hover是您懸停的鏈接
  • a:focus匹配當前被聚焦的鏈接(類似於被懸停,但使用鍵盤而不是鼠標)
  • a:active匹配你當前點擊的鏈接

在 CSS 中大約有 60 個偽類。 它們中的絕大多數允許您根據它們的狀態過濾項目(例如,您可以使用:read-only偽類來選擇只讀元素)。 但這條規則有一些有趣的“例外”值得一提。

但在我們開始之前,只是一個快速的旁注:注意如何區分偽類和偽元素,因為前者以單個冒號 ( :開頭,而後者以兩個 ( :: :) 開頭。

使用“child”和“of-type”偽類選擇元素的子元素

還記得我們之前看到的例子,我們添加了一個豎線來分隔列表的元素嗎? 好吧,如果您仔細觀察,您會發現我們設置的規則不太適用:

因為最後一個元素還包括一個豎線,即使它不應該。 如果我們想刪除它,我們可以這樣做:

 ul li { display: inline; } ul li::after { color: #21acde; content: " | "; display: inline-block; } ul li:last-child::after { display: none; }

與您想像的完全一樣:

正如你所看到的,我們所做的只是使用偽類:last-child添加一個新規則,它允許我們選擇ul列表中的最後一個li元素,一旦有了它,就隱藏它的偽元素::afterdisplay屬性設置為none

* -child 和 * -of-type 的特殊功能

*-child偽類有三種變體:

  • :first-child匹配元素的第一個子元素(呵呵!)
  • :last-child做同樣的事情,但後者
  • :nth-child(i) ,你猜對了,選擇第i個元素(例如, :nth-child(2)匹配第二個孩子)

因此,讓我們看看並考慮以下 CSS:

 li strong:first-child { color: orange; text-decoration: underline; }

以及以下 HTML 片段:

 <ol> <li>Lorem <strong>ipsum</strong> dolor <strong>sit</strong> amet.</li> <li><em>Lorem</em> <strong>ipsum</strong> dolor <strong>sit</strong> amet.</li> <li>Lorem <strong>ipsum</strong> dolor <em><strong>sit</strong></em> amet.</li> </ol>

你認為會發生什麼? 原則上,似乎在所有三種情況下,單詞ipsum都會是橙色並帶有下劃線,因為ipsum是每個li元素中的第一個strong子元素,對吧? 讓我們來看看:

  1. Lorem ipsum dolor sit amet。
  2. Lorem ipsum dolor sit amet。
  3. Lorem ipsum dolor sit amet。

嗯,夠近了。 你能猜到為什麼會這樣嗎?

:first-child偽類適用於元素的第一個子元素。 在第一句中, ipsum是第一個strong標籤,恰好是第一個孩子。 在第二個句子中,第一個子節點是em (帶有單詞Lorem ),然後是帶有單詞ipsumstrong標籤。 因此,這個強標籤並不是“第一個孩子”。 最後,在第三句中,有兩個標籤符合我們的規則: ipsum (就像第一句一樣)和sat 。 請注意sat是一個strong標籤,它是其父標籤 ( em ) 的第一個子標籤。

那麼,如果我們想在每個li項目的第一個strong標籤下劃線怎麼辦? 好吧,我們必須使用不同的偽類,並確保我們只匹配li的直接子元素:

 li > strong:first-of-type { color: orange; text-decoration: underline; }

按預期工作:

  1. Lorem ipsum dolor sit amet。
  2. Lorem ipsum dolor sit amet。
  3. Lorem ipsum dolor sit amet。

很厲害吧? 同樣,這個偽類有三種變體:

  • x:first-of-type匹配類型為x的第一個同級
  • x:last-of-type選擇最後一個
  • x:nth-of-type(i)匹配類型為x的第i個兄弟姐妹

:not選擇對立面

最後,我今天要和大家討論的偽類是:not:not是一個偽類,它匹配那些符合特定屬性的元素。 例如,讓我們回到之前的示例:

為了解決 bar 出現在最後一個元素的問題,我們基本上 (1) 將 bar 添加到所有li元素和 (2) 覆蓋最後一個元素中的規則並隱藏它:

 ul li { display: inline; } ul li::after { color: #21acde; content: " | "; display: inline-block; } ul li:last-child::after { display: none; }

但這似乎不是很理想,不是嗎? 我們在第一個 tule 上過衝,然後我們需要在最後一個元素中修復我們的樣式。 我們真正想要的是將欄添加到除最後一個之外的所有元素......

好吧,我們可以通過應用偽類:not並將其與:last-child結合來實現這一點:

 ul li { display: inline; } ul li:not(:last-child)::after { color: #21acde; content: " | "; display: inline-block; }

它將樣式應用於不是最後一個元素( :not(:last-child) )的所有li元素,這完美地描述了我們的目標,從而解決了我們的問題:

總之

CSS 偽元素和偽類讓我們在訪問我們網站的不同元素時更加精確。 有了它們,我們可以編寫更簡潔、更具體的 CSS 規則,從而簡化其維護並避免為特定情況不斷覆蓋通用規則的可能性。

我希望你喜歡這篇文章,如果你喜歡,請與你的朋友分享!

JFL 在 Unsplash 上的精選圖片。