關於二者的區別,實際上是很古老的問題。可是時至今日,因爲各類網絡誤傳以及一些不負責任的書籍誤筆,仍然有至關多的人將僞類與僞元素混爲一談,甚至不乏不少CSS老手。早些年剛入行的時候,我本身也被深深誤導,由於論壇裏的帖子大多不關心這種概念的細微差異,即便有人出來講一句:「這兩個是不一樣的」,也只是被更多的帖子淹沒掉而已。因此以爲有必要寫下這些我所知的部分,這裏着重寫的是爲何這二者不一樣,以及一些平時容易錯過的細節。
不管是僞類仍是僞元素,都屬於CSS選擇器的範疇。因此它們的定義能夠在CSS標準的選擇器章節找到。分別是 CSS2.1 Selectors 和 CSS Selector Level 3,二者都已是推薦標準。
標準的定義
在CSS2.1裏,5.10 Pseudo-elements and pseudo-classes 描述了這兩個概念的由來,它們是被一同說起的。但到了 Selector Level 3 裏,它們就被分開到兩個小節里加以區分。但不管如何,僞類和僞元素的引入都是由於在文檔樹裏有些信息沒法被充分描述,好比CSS沒有「段落的第一行」之類的選擇器,而這在一些出版場景裏又是必須的。用標準裏的話說:
CSS introduces the concepts of pseudo-elements and pseudo-classes to permit formatting based on information that lies outside the document tree.
簡單翻譯一下,就是:
CSS 引入僞類和僞元素的概念是爲了實現基於文檔樹以外的信息的格式化
這麼說很抽象,其實就是爲了描述一些現有CSS沒法描述的東西。缺乏什麼,則引入什麼,不論是標準,仍是人,都是如此成長而來。
僞類與僞元素的區別
這裏我大能夠列一個表格,把全部的僞類和僞元素分開羅列,但這未免太形式化,與其記住「哪些是哪些不是」,不如真正地加以區分。僞類和僞元素自己就有一個根本的不一樣之處,這點直接體如今了標準的描述語句上。
先看一個僞元素 first-line 例子。如今有一段HTML,內容是一個段落:
php
若是我要描述這個段落的第一行,在不用僞元素的狀況下,我會怎麼作?想來我必定要嵌套一層 span,而後加上類名:
瀏覽器
再反觀一個僞類 first-child 的例子,有一個簡單的列表:
網絡
若是我要描述 ul 的第一個元素,我無須嵌套新的元素,我只須給第一個已經存在的 li 添加一個類名就能夠了:
ide
儘管,第一行和第一個元素,這二者的語意類似,但最後做用的效果卻徹底不一樣。因此,僞類和僞元素的根本區別在於:它們是否創造了新的元素(抽象)。從咱們模仿其意義的角度來看,若是須要添加新元素加以標識的,就是僞元素,反之,若是隻須要在既有元素上添加類別的,就是僞類。而這也是爲何,標準精確地使用 「create」 一詞來解釋僞元素,而使用 「classify」 一詞來解釋僞類的緣由。一個描述的是新建立出來的「幽靈」元素,另外一個則是描述已經存在的符合「幽靈」類別的元素。
僞類一開始單單只是用來表示一些元素的動態狀態,典型的就是連接的各個狀態(LVHA)。隨後CSS2標準擴展了其概念範圍,使其成爲了全部邏輯上存在但在文檔樹中卻無須標識的「幽靈」分類。
僞元素則表明了某個元素的子元素,這個子元素雖然在邏輯上存在,但卻並不實際存在於文檔樹中。
僞類和僞元素混淆的由來
最爲混淆的,多是大部分人都將 :before 和 :after 這樣的僞元素隨口叫作僞類,並且即便在概念混淆的狀況下,實際使用上也毫無問題——由於即便概念混淆,對真正使用也不會形成多少麻煩:)
CSS Selector Level 3 爲了區分這二者的混淆,而特地用冒號加以區分:
僞類用一個冒號表示 :first-child
僞元素則使用兩個冒號表示 ::first-line
而且規定,瀏覽器既要兼容CSS1和2裏既存的僞元素的單冒號表示,同時又要不兼容CSS3新引入的僞元素的單冒號表示。後來的結果你們都知道,由於低版本IE對雙冒號的兼容問題,幾乎全部的CSSer在寫樣式的時候都不約而同的使用了單冒號。這無形中,讓這種混淆延續了下來。而CSS3新僞元素的使用到目前爲止,還遠遠不成氣候。
僞類和僞元素使用上須要注意的地方
明白其不一樣以後,就須要注意和考慮在實際使用上的一些問題。好比:僞類和僞元素的選擇器特殊性(優先級)如何計算?
我在以前的 CSS選擇器距離無關 一文中,翻譯過CSS標準的計算選擇器的特殊性這一部分,看完那部分,答案就清楚了:除了否認僞類的特殊規定外,分開各自做爲真正的類和元素計算。
雖然標準之後的版本可能會容許選擇器多僞元素的狀況,但就目前爲止,僞元素在一個選擇器裏只能出現一次,而且只能出如今末尾。實則,僞元素是選中了某個元素的符合邏輯的某個實際卻不存在的部分,因此應用中也不會有人將其誤寫成多個。僞類則是像真正的類同樣發揮着類的做用,沒有數量上的限制,只要不是相互排斥的僞類,也能夠同時使用在相同的元素上。關於CSS3選擇器的詳細解釋,推薦 rogerjohansson 的 CSS 3 selectors explained。
結束語
原本只是想稍稍寫點,不想話又多了…到了最後,我一度以爲本身還漏了不少,不斷在腦海裏搜索,但可能只能下次在補充了。寫這篇的目的是爲下篇《CSS僞類與CSS僞元素的典型應用》作個鋪墊,不想理論的東西一寫本身就開始廢話連篇了,慚愧…回看本篇,本身的思路跳的有些亂了,洋洋灑灑這麼多字,可能歸納起來沒幾句話,但若是但願儘量表達清楚,則又免不了冗餘過頭。理論老是顯得枯燥了些,下篇閒談應用應該不至於這麼沉悶:)spa