前端er們大都或多或少地接觸過CSS偽類和偽元素,比如最常見的:focus
,:hover
以及<a>
標(biāo)簽的:link
锹雏、visited
等巴比,偽元素較常見的比如:before
、:after
等逼侦。
其實上面提到的這些偽類和偽元素都是CSS1和CSS2中的概念匿辩,CSS1和CSS2中對偽類的偽元素的區(qū)別比較模糊,甚至經(jīng)常有同行將:before
榛丢、:after
稱為偽類铲球。CSS3對這兩個概念做了相對較清晰地概念,并且在語法上也很明顯的講二者區(qū)別開晰赞。
偽類 - pseudo classes
首先看看CSS2中對偽類的定義:
單單看定義完全不懂在講什么。截止CSS2掖鱼,偽類有以下幾種(偷個懶然走,截圖引自W3School):
然后是CSS3對偽類的定義:
The pseudo-class concept is introduced to permit selection based on information that lies outside of the document tree or that cannot be expressed using the other simple selectors.
A pseudo-class always consists of a "colon" (:) followed by the name of the pseudo-class and optionally by a value between parentheses.
Pseudo-classes are allowed in all sequences of simple selectors contained in a selector. Pseudo-classes are allowed anywhere in sequences of simple selectors, after the leading type selector or universal selector (possibly omitted). Pseudo-class names are case-insensitive. Some pseudo-classes are mutually exclusive, while others can be applied simultaneously to the same element. Pseudo-classes may be dynamic, in the sense that an element may acquire or lose a pseudo-class while a user interacts with the document.
簡單翻譯一下:
偽類存在的意義是為了通過選擇器找到那些不存在與DOM樹中的信息以及不能被常規(guī)CSS選擇器獲取到的信息。
偽類由一個冒號
:
開頭戏挡,冒號后面是偽類的名稱和包含在圓括號中的可選參數(shù)芍瑞。
任何常規(guī)選擇器可以再任何位置使用偽類。偽類語法不區(qū)別大小寫褐墅。一些偽類的作用會互斥拆檬,另外一些偽類可以同時被同一個元素使用洪己。并且,為了滿足用戶在操作DOM時產(chǎn)生的DOM結(jié)構(gòu)改變竟贯,偽類也可以是動態(tài)的答捕。
其實第一段話就囊括CSS3偽類的全部定義了,這段話中指出CSS3偽類的功能有兩種:
- 獲取不存在與DOM樹中的信息屑那。比如
<a>
標(biāo)簽的:link
拱镐、visited
等,這些信息不存在與DOM樹結(jié)構(gòu)中持际,只能通過CSS選擇器來獲任掷拧; - 獲取不能被常規(guī)CSS選擇器獲取的信息选酗。比如偽類
:target
阵难,它的作用是匹配文檔(頁面)的URI中某個標(biāo)志符的目標(biāo)元素,例如我們可以通過如下代碼來實現(xiàn)頁面內(nèi)的區(qū)域跳轉(zhuǎn):
<ul class="tabs">
<li><a href="#tab1">標(biāo)簽一</a></li>
<li><a href="#tab2">標(biāo)簽二</a></li>
<li><a href="#tab3">標(biāo)簽三</a></li>
</ul>
<div id="tab1" class="tab_content">
<!--tabed content--></div>
<div id="tab2" class="tab_content">
<!--tabed content--></div>
<div id="tab3" class="tab_content">
<!--tabed content--></div>
CSS代碼如下:
.tab_content {
height: 800px;
background: red;
margin-bottom: 100px;
}
#tab1:target, #tab2:target, #tab3:target {
background:blue;
}
當(dāng)然芒填,通過JavaScript來獲取window.location.hash
同樣可以實現(xiàn)上例中的效果,但這是另外一回事了空繁〉钏ィ總之,:target
通過CSS實現(xiàn)了常規(guī)CSS無法實現(xiàn)的邏輯盛泡。
其實對比來看闷祥,CSS2中對偽類的定義也是合理地,但是它并未指出“某些選擇器”是“哪些選擇器”傲诵,CSS3對偽類的定義就顯得明確了很多凯砍。
再舉個栗子,通過:nth-child()
偽類可以實現(xiàn)一些很有意思的效果拴竹,比如:
table tr:nth-child(2n) td{
background-color: #ccc;
}
table tr:nth-child(2n+1) td{
background-color: #fff;
}
table tr:nth-child(2n+1):nth-child(5n) td{
background-color: #f0f;
}
上面的代碼將所有偶數(shù)行背景色設(shè)置為#ccc
悟衩,不能被5整除的奇數(shù)行設(shè)置背景色#fff
,能夠被5整除的奇數(shù)行設(shè)置背景色#f0f
栓拜。
如果不使用偽類而是使用JavaScript代碼來實現(xiàn)上述的效果座泳,恐怕要復(fù)雜很多。
可以總結(jié)出:nth-child()
偽類的效果是將被常規(guī)css選擇器篩選出的元素按照既定規(guī)定進行再次篩選幕与。
CSS3中還引入了許多新的偽類挑势,感興趣的讀者可以參考這里。
偽元素 - Pseudo-elements
CSS2中對偽元素的定義:
好吧潮饱,跟偽類的定義完全一樣有木有(吐槽一下W3School的翻譯)。其實人家這樣翻譯也沒有錯诫给,本來CSS2對偽類和偽元素的定義就是完全一樣的:
CSS introduces the concepts of pseudo-elements and pseudo-classes to permit formatting based on information that lies outside the document tree.
截止CSS2香拉,偽元素有以下幾種:
然后再看CSS3中偽元素的定義:
Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element's content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).
A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.
This :: notation is introduced by the current document in order to establish a discrimination between pseudo-classes and pseudo-elements. For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after). This compatibility is not allowed for the new pseudo-elements introduced in this specification.
Only one pseudo-element may appear per selector, and if present it must appear after the sequence of simple selectors that represents the subjects of the selector.
Note: A future version of this specification may allow multiple pseudo-elements per selector.
簡單翻譯一下:
偽元素在DOM樹中創(chuàng)建了一些抽象元素啦扬,這些抽象元素是不存在于文檔語言里的(可以理解為html源碼)。比如:documen接口不提供訪問元素內(nèi)容的第一個字或者第一行的機制缕溉,而偽元素可以使開發(fā)者可以提取到這些信息考传。并且,一些偽元素可以使開發(fā)者獲取到不存在于源文檔中的內(nèi)容(比如常見的
::before
,::after
)证鸥。
偽元素的由兩個冒號
::
開頭僚楞,然后是偽元素的名稱。
使用兩個冒號
::
是為了區(qū)別偽類和偽元素(CSS2中并沒有區(qū)別)枉层。當(dāng)然泉褐,考慮到兼容性,CSS2中已存的偽元素仍然可以使用一個冒號:
的語法鸟蜡,但是CSS3中新增的偽元素必須使用兩個冒號::
膜赃。
一個選擇器只能使用一個偽元素,并且偽元素必須處于選擇器語句的最后揉忘。
注:不排除未來會加入同時使用多個偽元素的機制跳座。
同樣,第一段話是偽元素的清晰定義泣矛,也是偽元素與偽類最大的區(qū)別疲眷。簡單來說,偽元素創(chuàng)建了一個虛擬容器您朽,這個容器不包含任何DOM元素狂丝,但是可以包含內(nèi)容。另外哗总,開發(fā)者還可以為偽元素定制樣式几颜。
已::first-line
為例,它獲取了指定元素的第一行內(nèi)容并且將第一行的內(nèi)容加入到虛擬容器中讯屈。如果通過JavaScript來實現(xiàn)這個邏輯蛋哭,那么要考慮的因素就太多了,比如制定元素的寬度耻煤、字體大小具壮,甚至浮動元素的圖文混排等等。當(dāng)然哈蝇,這些問題確實是可以用JavaScript來解決的棺妓,但是相對于::first-line
簡簡單單的幾個字,用JavaScript恐怕不止這些吧炮赦!
舉個綜合使用偽類和偽元素的栗子:
q:lang(de)::after{
content: " (German) ";
}
q:lang(en)::after{
content: " (English) ";
}
q:lang(fr)::after{
content: " (French) ";
}
q:not(:lang(fr)):not(:lang(de)):not(:lang(en))::after{
content: " (Unrecognized language) ";
}
以上代碼通過偽類"lang
獲取不同lang
屬性的節(jié)點怜跑,并為之設(shè)置偽元素::after
,偽元素的內(nèi)容是此節(jié)點的語言類型。
最后性芬,總結(jié)一下偽類與偽元素的特性及其區(qū)別:
- 偽類本質(zhì)上是為了彌補常規(guī)CSS選擇器的不足峡眶,以便獲取到更多信息;
- 偽元素本質(zhì)上是創(chuàng)建了一個有內(nèi)容的虛擬容器植锉;
- CSS3中偽類和偽元素的語法不同辫樱;
- 可以同時使用多個偽類,而只能同時使用一個偽元素俊庇;
來源:才子鍋鍋博客 https://www.cnblogs.com/ihardcoder/