CSS偽類(lèi)與CSS偽元素的區(qū)別及由來(lái)具體說(shuō)明
發(fā)布時(shí)間:2012-12-07 09:44:58 作者:佚名
我要評(píng)論
關(guān)于兩者的區(qū)別,其實(shí)是很古老的問(wèn)題.這里著重寫(xiě)的是為什么這兩者不同,以及一些平時(shí)容易錯(cuò)過(guò)的細(xì)節(jié),需要的朋友可以參考下
關(guān)于兩者的區(qū)別,其實(shí)是很古老的問(wèn)題。但是時(shí)至今日,由于各種網(wǎng)絡(luò)誤傳以及一些不負(fù)責(zé)任的書(shū)籍誤筆,仍然有相當(dāng)多的人將偽類(lèi)與偽元素混為一談,甚至不乏很多CSS老手。早些年剛?cè)胄械臅r(shí)候,我自己也被深深誤導(dǎo),因?yàn)檎搲锏奶哟蠖嗖魂P(guān)心這種概念的細(xì)微差別,即使有人出來(lái)說(shuō)一句:“這兩個(gè)是不同的”,也只是被更多的帖子淹沒(méi)掉而已。所以覺(jué)得有必要寫(xiě)下這些我所知的部分,這里著重寫(xiě)的是為什么這兩者不同,以及一些平時(shí)容易錯(cuò)過(guò)的細(xì)節(jié)。
無(wú)論是偽類(lèi)還是偽元素,都屬于CSS選擇器的范疇。所以它們的定義可以在CSS標(biāo)準(zhǔn)的選擇器章節(jié)找到。分別是 CSS2.1 Selectors 和 CSS Selector Level 3,兩者都已經(jīng)是推薦標(biāo)準(zhǔn)。
標(biāo)準(zhǔn)的定義
在CSS2.1里,5.10 Pseudo-elements and pseudo-classes 描述了這兩個(gè)概念的由來(lái),它們是被一同提及的。但到了 Selector Level 3 里,它們就被分開(kāi)到兩個(gè)小節(jié)里加以區(qū)分。但無(wú)論如何,偽類(lèi)和偽元素的引入都是因?yàn)樵谖臋n樹(shù)里有些信息無(wú)法被充分描述,比如CSS沒(méi)有“段落的第一行”之類(lèi)的選擇器,而這在一些出版場(chǎng)景里又是必須的。用標(biāo)準(zhǔn)里的話說(shuō):
CSS introduces the concepts of pseudo-elements and pseudo-classes to permit formatting based on information that lies outside the document tree.
簡(jiǎn)單翻譯一下,就是:
CSS 引入偽類(lèi)和偽元素的概念是為了實(shí)現(xiàn)基于文檔樹(shù)之外的信息的格式化
這么說(shuō)很抽象,其實(shí)就是為了描述一些現(xiàn)有CSS無(wú)法描述的東西。缺少什么,則引入什么,不管是標(biāo)準(zhǔn),還是人,都是如此成長(zhǎng)而來(lái)。
偽類(lèi)與偽元素的區(qū)別
這里我大可以列一個(gè)表格,把所有的偽類(lèi)和偽元素分開(kāi)羅列,但這未免太形式化,與其記住“哪些是哪些不是”,不如真正地加以區(qū)分。偽類(lèi)和偽元素本身就有一個(gè)根本的不同之處,這點(diǎn)直接體現(xiàn)在了標(biāo)準(zhǔn)的描述語(yǔ)句上。
先看一個(gè)偽元素 first-line 例子?,F(xiàn)在有一段HTML,內(nèi)容是一個(gè)段落:
<p>I am the bone of my sword. Steel is my body, and fire is my blood.
I have created over a thoustand blades.
Unknown to Death.Nor known to Life. Have withstood pain to create many weapon.
Yet, those hands will never hold anything. So as I pray, unlimited blade works.</p>
如果我要描述這個(gè)段落的第一行,在不用偽元素的情況下,我會(huì)怎么做?想來(lái)我一定要嵌套一層 span,然后加上類(lèi)名:
<p><span class="first-line">I am the bone of my sword. Steel is my body, and fire is my blood. </span>
I have created over a thoustand blades.
Unknown to Death.Nor known to Life. Have withstood pain to create many weapon.
Yet, those hands will never hold anything. So as I pray, unlimited blade works.</p>
再反觀一個(gè)偽類(lèi) first-child 的例子,有一個(gè)簡(jiǎn)單的列表:
<ul>
<li></li>
<li></li>
</ul>
如果我要描述 ul 的第一個(gè)元素,我無(wú)須嵌套新的元素,我只須給第一個(gè)已經(jīng)存在的 li 添加一個(gè)類(lèi)名就可以了:
<ul>
<li class="first-child"></li>
<li></li>
</ul>
盡管,第一行和第一個(gè)元素,這兩者的語(yǔ)意相似,但最后作用的效果卻完全不同。所以,偽類(lèi)和偽元素的根本區(qū)別在于:它們是否創(chuàng)造了新的元素(抽象)。從我們模仿其意義的角度來(lái)看,如果需要添加新元素加以標(biāo)識(shí)的,就是偽元素,反之,如果只需要在既有元素上添加類(lèi)別的,就是偽類(lèi)。而這也是為什么,標(biāo)準(zhǔn)精確地使用 “create” 一詞來(lái)解釋偽元素,而使用 “classify” 一詞來(lái)解釋偽類(lèi)的原因。一個(gè)描述的是新創(chuàng)建出來(lái)的“幽靈”元素,另一個(gè)則是描述已經(jīng)存在的符合“幽靈”類(lèi)別的元素。
偽類(lèi)一開(kāi)始單單只是用來(lái)表示一些元素的動(dòng)態(tài)狀態(tài),典型的就是鏈接的各個(gè)狀態(tài)(LVHA)。隨后CSS2標(biāo)準(zhǔn)擴(kuò)展了其概念范圍,使其成為了所有邏輯上存在但在文檔樹(shù)中卻無(wú)須標(biāo)識(shí)的“幽靈”分類(lèi)。
偽元素則代表了某個(gè)元素的子元素,這個(gè)子元素雖然在邏輯上存在,但卻并不實(shí)際存在于文檔樹(shù)中。
偽類(lèi)和偽元素混淆的由來(lái)
最為混淆的,可能是大部分人都將 :before 和 :after 這樣的偽元素隨口叫做偽類(lèi),而且即使在概念混淆的情況下,實(shí)際使用上也毫無(wú)問(wèn)題——因?yàn)榧词垢拍罨煜?,?duì)真正使用也不會(huì)造成多少麻煩:)
CSS Selector Level 3 為了區(qū)分這兩者的混淆,而特意用冒號(hào)加以區(qū)分:
偽類(lèi)用一個(gè)冒號(hào)表示 :first-child
偽元素則使用兩個(gè)冒號(hào)表示 ::first-line
并且規(guī)定,瀏覽器既要兼容CSS1和2里既存的偽元素的單冒號(hào)表示,同時(shí)又要不兼容CSS3新引入的偽元素的單冒號(hào)表示。后來(lái)的結(jié)果大家都知道,因?yàn)榈桶姹綢E對(duì)雙冒號(hào)的兼容問(wèn)題,幾乎所有的CSSer在寫(xiě)樣式的時(shí)候都不約而同的使用了單冒號(hào)。這無(wú)形中,讓這種混淆延續(xù)了下來(lái)。而CSS3新偽元素的使用到目前為止,還遠(yuǎn)遠(yuǎn)不成氣候。
偽類(lèi)和偽元素使用上需要注意的地方
明白其不同之后,就需要注意和考慮在實(shí)際使用上的一些問(wèn)題。比如:偽類(lèi)和偽元素的選擇器特殊性(優(yōu)先級(jí))如何計(jì)算?
我在之前的 CSS選擇器距離無(wú)關(guān) 一文中,翻譯過(guò)CSS標(biāo)準(zhǔn)的計(jì)算選擇器的特殊性這一部分,看完那部分,答案就清楚了:除了否定偽類(lèi)的特殊規(guī)定外,分開(kāi)各自作為真正的類(lèi)和元素計(jì)算。
雖然標(biāo)準(zhǔn)以后的版本可能會(huì)允許選擇器多偽元素的情況,但就目前為止,偽元素在一個(gè)選擇器里只能出現(xiàn)一次,并且只能出現(xiàn)在末尾。實(shí)則,偽元素是選中了某個(gè)元素的符合邏輯的某個(gè)實(shí)際卻不存在的部分,所以應(yīng)用中也不會(huì)有人將其誤寫(xiě)成多個(gè)。偽類(lèi)則是像真正的類(lèi)一樣發(fā)揮著類(lèi)的作用,沒(méi)有數(shù)量上的限制,只要不是相互排斥的偽類(lèi),也可以同時(shí)使用在相同的元素上。關(guān)于CSS3選擇器的詳細(xì)解釋,推薦 rogerjohansson 的 CSS 3 selectors explained。
結(jié)束語(yǔ)
本來(lái)只是想稍稍寫(xiě)點(diǎn),不想話又多了…到了最后,我一度覺(jué)得自己還漏了很多,不斷在腦海里搜索,但可能只能下次在補(bǔ)充了。寫(xiě)這篇的目的是為下篇《CSS偽類(lèi)與CSS偽元素的典型應(yīng)用》做個(gè)鋪墊,不想理論的東西一寫(xiě)自己就開(kāi)始廢話連篇了,慚愧…回看本篇,自己的思路跳的有些亂了,洋洋灑灑這么多字,可能概括起來(lái)沒(méi)幾句話,但如果希望盡可能表達(dá)清楚,則又免不了冗余過(guò)頭。理論總是顯得枯燥了些,下篇閑談應(yīng)用應(yīng)該不至于這么沉悶:)
無(wú)論是偽類(lèi)還是偽元素,都屬于CSS選擇器的范疇。所以它們的定義可以在CSS標(biāo)準(zhǔn)的選擇器章節(jié)找到。分別是 CSS2.1 Selectors 和 CSS Selector Level 3,兩者都已經(jīng)是推薦標(biāo)準(zhǔn)。
標(biāo)準(zhǔn)的定義
在CSS2.1里,5.10 Pseudo-elements and pseudo-classes 描述了這兩個(gè)概念的由來(lái),它們是被一同提及的。但到了 Selector Level 3 里,它們就被分開(kāi)到兩個(gè)小節(jié)里加以區(qū)分。但無(wú)論如何,偽類(lèi)和偽元素的引入都是因?yàn)樵谖臋n樹(shù)里有些信息無(wú)法被充分描述,比如CSS沒(méi)有“段落的第一行”之類(lèi)的選擇器,而這在一些出版場(chǎng)景里又是必須的。用標(biāo)準(zhǔn)里的話說(shuō):
CSS introduces the concepts of pseudo-elements and pseudo-classes to permit formatting based on information that lies outside the document tree.
簡(jiǎn)單翻譯一下,就是:
CSS 引入偽類(lèi)和偽元素的概念是為了實(shí)現(xiàn)基于文檔樹(shù)之外的信息的格式化
這么說(shuō)很抽象,其實(shí)就是為了描述一些現(xiàn)有CSS無(wú)法描述的東西。缺少什么,則引入什么,不管是標(biāo)準(zhǔn),還是人,都是如此成長(zhǎng)而來(lái)。
偽類(lèi)與偽元素的區(qū)別
這里我大可以列一個(gè)表格,把所有的偽類(lèi)和偽元素分開(kāi)羅列,但這未免太形式化,與其記住“哪些是哪些不是”,不如真正地加以區(qū)分。偽類(lèi)和偽元素本身就有一個(gè)根本的不同之處,這點(diǎn)直接體現(xiàn)在了標(biāo)準(zhǔn)的描述語(yǔ)句上。
先看一個(gè)偽元素 first-line 例子?,F(xiàn)在有一段HTML,內(nèi)容是一個(gè)段落:
復(fù)制代碼
代碼如下:<p>I am the bone of my sword. Steel is my body, and fire is my blood.
I have created over a thoustand blades.
Unknown to Death.Nor known to Life. Have withstood pain to create many weapon.
Yet, those hands will never hold anything. So as I pray, unlimited blade works.</p>
如果我要描述這個(gè)段落的第一行,在不用偽元素的情況下,我會(huì)怎么做?想來(lái)我一定要嵌套一層 span,然后加上類(lèi)名:
復(fù)制代碼
代碼如下:<p><span class="first-line">I am the bone of my sword. Steel is my body, and fire is my blood. </span>
I have created over a thoustand blades.
Unknown to Death.Nor known to Life. Have withstood pain to create many weapon.
Yet, those hands will never hold anything. So as I pray, unlimited blade works.</p>
再反觀一個(gè)偽類(lèi) first-child 的例子,有一個(gè)簡(jiǎn)單的列表:
復(fù)制代碼
代碼如下:<ul>
<li></li>
<li></li>
</ul>
如果我要描述 ul 的第一個(gè)元素,我無(wú)須嵌套新的元素,我只須給第一個(gè)已經(jīng)存在的 li 添加一個(gè)類(lèi)名就可以了:
復(fù)制代碼
代碼如下:<ul>
<li class="first-child"></li>
<li></li>
</ul>
盡管,第一行和第一個(gè)元素,這兩者的語(yǔ)意相似,但最后作用的效果卻完全不同。所以,偽類(lèi)和偽元素的根本區(qū)別在于:它們是否創(chuàng)造了新的元素(抽象)。從我們模仿其意義的角度來(lái)看,如果需要添加新元素加以標(biāo)識(shí)的,就是偽元素,反之,如果只需要在既有元素上添加類(lèi)別的,就是偽類(lèi)。而這也是為什么,標(biāo)準(zhǔn)精確地使用 “create” 一詞來(lái)解釋偽元素,而使用 “classify” 一詞來(lái)解釋偽類(lèi)的原因。一個(gè)描述的是新創(chuàng)建出來(lái)的“幽靈”元素,另一個(gè)則是描述已經(jīng)存在的符合“幽靈”類(lèi)別的元素。
偽類(lèi)一開(kāi)始單單只是用來(lái)表示一些元素的動(dòng)態(tài)狀態(tài),典型的就是鏈接的各個(gè)狀態(tài)(LVHA)。隨后CSS2標(biāo)準(zhǔn)擴(kuò)展了其概念范圍,使其成為了所有邏輯上存在但在文檔樹(shù)中卻無(wú)須標(biāo)識(shí)的“幽靈”分類(lèi)。
偽元素則代表了某個(gè)元素的子元素,這個(gè)子元素雖然在邏輯上存在,但卻并不實(shí)際存在于文檔樹(shù)中。
偽類(lèi)和偽元素混淆的由來(lái)
最為混淆的,可能是大部分人都將 :before 和 :after 這樣的偽元素隨口叫做偽類(lèi),而且即使在概念混淆的情況下,實(shí)際使用上也毫無(wú)問(wèn)題——因?yàn)榧词垢拍罨煜?,?duì)真正使用也不會(huì)造成多少麻煩:)
CSS Selector Level 3 為了區(qū)分這兩者的混淆,而特意用冒號(hào)加以區(qū)分:
偽類(lèi)用一個(gè)冒號(hào)表示 :first-child
偽元素則使用兩個(gè)冒號(hào)表示 ::first-line
并且規(guī)定,瀏覽器既要兼容CSS1和2里既存的偽元素的單冒號(hào)表示,同時(shí)又要不兼容CSS3新引入的偽元素的單冒號(hào)表示。后來(lái)的結(jié)果大家都知道,因?yàn)榈桶姹綢E對(duì)雙冒號(hào)的兼容問(wèn)題,幾乎所有的CSSer在寫(xiě)樣式的時(shí)候都不約而同的使用了單冒號(hào)。這無(wú)形中,讓這種混淆延續(xù)了下來(lái)。而CSS3新偽元素的使用到目前為止,還遠(yuǎn)遠(yuǎn)不成氣候。
偽類(lèi)和偽元素使用上需要注意的地方
明白其不同之后,就需要注意和考慮在實(shí)際使用上的一些問(wèn)題。比如:偽類(lèi)和偽元素的選擇器特殊性(優(yōu)先級(jí))如何計(jì)算?
我在之前的 CSS選擇器距離無(wú)關(guān) 一文中,翻譯過(guò)CSS標(biāo)準(zhǔn)的計(jì)算選擇器的特殊性這一部分,看完那部分,答案就清楚了:除了否定偽類(lèi)的特殊規(guī)定外,分開(kāi)各自作為真正的類(lèi)和元素計(jì)算。
雖然標(biāo)準(zhǔn)以后的版本可能會(huì)允許選擇器多偽元素的情況,但就目前為止,偽元素在一個(gè)選擇器里只能出現(xiàn)一次,并且只能出現(xiàn)在末尾。實(shí)則,偽元素是選中了某個(gè)元素的符合邏輯的某個(gè)實(shí)際卻不存在的部分,所以應(yīng)用中也不會(huì)有人將其誤寫(xiě)成多個(gè)。偽類(lèi)則是像真正的類(lèi)一樣發(fā)揮著類(lèi)的作用,沒(méi)有數(shù)量上的限制,只要不是相互排斥的偽類(lèi),也可以同時(shí)使用在相同的元素上。關(guān)于CSS3選擇器的詳細(xì)解釋,推薦 rogerjohansson 的 CSS 3 selectors explained。
結(jié)束語(yǔ)
本來(lái)只是想稍稍寫(xiě)點(diǎn),不想話又多了…到了最后,我一度覺(jué)得自己還漏了很多,不斷在腦海里搜索,但可能只能下次在補(bǔ)充了。寫(xiě)這篇的目的是為下篇《CSS偽類(lèi)與CSS偽元素的典型應(yīng)用》做個(gè)鋪墊,不想理論的東西一寫(xiě)自己就開(kāi)始廢話連篇了,慚愧…回看本篇,自己的思路跳的有些亂了,洋洋灑灑這么多字,可能概括起來(lái)沒(méi)幾句話,但如果希望盡可能表達(dá)清楚,則又免不了冗余過(guò)頭。理論總是顯得枯燥了些,下篇閑談應(yīng)用應(yīng)該不至于這么沉悶:)
相關(guān)文章

詳解如何使用CSS3中的結(jié)構(gòu)偽類(lèi)選擇器和偽元素選擇器
這篇文章主要介紹了詳解如何使用CSS3中的結(jié)構(gòu)偽類(lèi)選擇器和偽元素選擇器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面2020-01-06- CSS偽元素能使我們添加案定的HTML元素之外的元素,這里我們就來(lái)解析CSS中的偽元素及其與偽類(lèi)的區(qū)別,需要的朋友可以參考下2016-06-27
- 這篇文章主要介紹了詳解CSS中的偽類(lèi)與偽元素及二者間的區(qū)別,實(shí)際上CSS3中規(guī)范了一種簡(jiǎn)單粗暴的方法,即偽類(lèi)前用一個(gè)冒號(hào)表示,而偽元素前用兩個(gè)冒號(hào)表示,這樣就不容易混淆了,2016-04-28
- 本文向大家展示了CSS的偽類(lèi)與偽元素,介紹的非常全面,這里推薦給大家參考下。2014-12-04
- 偽類(lèi)和偽元素不是真正意義上的html存在的類(lèi)和元素,他們的存在是為了方便對(duì)狀態(tài)和位置進(jìn)行樣式定義。具體他們之間有什么區(qū)別呢,這就是今天我們需要討論的問(wèn)題了2014-11-23
- 無(wú)論是偽類(lèi)還是偽元素,都屬于CSS選擇器的范疇。所以它們的定義可以在CSS標(biāo)準(zhǔn)的選擇器章節(jié)找到。分別是 CSS2.1 Selectors 和 CSS Selector Level 3,兩者都已經(jīng)是推薦標(biāo)準(zhǔn)2014-09-04
- CSS偽類(lèi)及偽元素選擇器,如超鏈接的a:link、a:visited、a:hover等等,本文整理了一些,喜歡的朋友可以收藏下2013-11-27
- css偽類(lèi)偽元素域高級(jí)選擇器的介紹,需要的朋友可以參考一下2013-02-26
這篇文章主要介紹了淺談CSS 偽元素&偽類(lèi)的妙用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)2020-09-01


