CSS中偽類與虛擬元素的概念是很容易混淆的
今天就來談談偽類與虛擬元素之間的區別
定義
首先先來看看偽類與虛擬元素的定義
w3c中對於它們是這麼解釋的
偽類:用於向某些選取器添加特殊的效果
虛擬元素:用於將特殊的效果添加到某些選取器
講道理,可能我語文不好,我覺得這兩句話是等價的 :-)
根本不能看出有什麼區別
都是對某些選取器“加特技”
標準有這麼一句話翻譯過來是這樣的
CSS 引入偽類和虛擬元素的概念是為了實現基於文檔樹之外的資訊的格式化
這話更抽象,其實意思就是對那些我們不能通過class、id等選擇元素的補充
區別
這個區別我們需要一個例子來理解
<p> <em>This</em> <em>is a text</em></p>
如果我們想要第一個em標籤字型顏色變紅怎麼做呢
使用我們熟悉的偽類很簡單
em:first-child { color: red;}
但是如果不存在偽類我們怎麼做呢
這是我們就需要為第一個em標籤添加類
<p> <em class="first-child">This</em> <em>is a text</em></p>
em.first-child { color: red;}
可以實現同樣的效果
<p> <em>This</em> <em>is a text</em></p>
還是這個例子
現在我想讓這個段落的第一個字母變紅
怎麼做呢
這回我們需要使用虛擬元素
p::first-letter { color: red;}
同樣假設虛擬元素不存在的情況
這時我們只能嵌套span標籤來實現
<p> <em><span>T</span>his</em> <em>is a text</em></p>
p span { color: red;}
看到這裡,相信大家已經清楚了為什麼一個叫做偽類,一個叫做虛擬元素
偽類的效果可以通過添加實際的類來實現
虛擬元素的效果可以通過添加實際的元素來實現
它們的本質區別就是是否抽象創造了新元素
曆史
偽類最開始的時候只是用來表示元素的動態(典型的錨偽類link、visited、hover、active)
在CSS2標準中對它進行了擴充讓它雖然邏輯存在但不需要在DOM樹中標識
虛擬元素代表了某個元素的子項目,雖然邏輯存在,但不存在於DOM樹
雖然它們的概念很容易被我們混淆
但是也不影響我們正常使用
我在CSS3選取器介紹及用法總結中說過
偽類只能使用“:”
而虛擬元素既可以使用“:”,也可以使用“::”
這裡我就解釋一下為什麼
CSS3中的標準是偽類使用單冒號“:”
而虛擬元素使用雙冒號“::”(避免混淆)
但是在此之前無論是偽類還是虛擬元素都使用單冒號“:”
所以為了保證相容虛擬元素兩種使用方法都是可以的
但是低版本IE有雙冒號相容問題
所以以前編寫樣式的人們對於偽類和虛擬元素就乾脆統統使用單冒號
導致這種混淆一直延續下來
注意
在使用偽類和虛擬元素的時候
有一點要特別注意
偽類就像真正的類一樣,可以疊加使用
沒有數量上限,只要不是互斥的
比如這樣
em:first-child:hover { color: red;}
這是完全可以的
但注意,這裡是“與”的關係
也就是說既要滿足“first-child”第一個子項目
又要滿足“hover”游標懸浮
虛擬元素就要嚴格的多
虛擬元素在一個選取器中只能出現一次,並且只能出現在末尾
(這裡有同學誤會了,所以我作出了修改)
像下面的樣式是無法生效的
p::first-letter:hover { /*錯誤的寫法:虛擬元素不是末尾*/ color: red;}
p::first-letter::selection { /*錯誤的寫法:虛擬元素出現了多個*/ color: red;}
再多說一句關於它們的優先順序
在計算權重的時候
偽類與類優先順序相同
虛擬元素與標籤優先順序相同
總結