在CSS中,模式匹配(pattern match)規(guī)則決定文檔樹上的元素使用究竟哪個樣式規(guī)則。這個模式就叫做選擇器(selector)。
CSS中的元素選擇器除了可以id(#
)、class(.
)、屬性([]
)選取元素以外,還有很重要的一類,就是根據(jù)元素的狀態(tài)來選取元素,包括偽類(pseudo-class)和偽元素(pseudo-element)。
這些傳統(tǒng)的選擇器,包括id選擇器、class選擇器、屬性選擇器、派生選擇器等等,他們是直接從HTML文檔的DOM樹中獲取元素的。而偽類和偽元素選擇器是預(yù)定義的,且是獨立文檔元素的。它們獲取元素的途徑也不是基于id、class、屬性這些基礎(chǔ)的元素特征,而是基于處于特殊狀態(tài)的元素(偽類),或者是元素中特別的內(nèi)容(偽元素)。當(dāng)然,偽類和偽元素的表示形式也使用:
(或者::
)與其它選擇器相區(qū)分。
什么叫偽類呢?
偽類是基于元素的特征而不是他們的id、class、屬性或者內(nèi)容。一般來說,元素的特征是不可以從DOM樹上推斷得到的,而且其是動態(tài)的,當(dāng)用戶和DOM進行交互的時候,元素可以獲得或者失去一個偽類。(這里有一個例外,就是:first-child
和:lang
是可以從DOM樹中推斷出來的。)
CSS的現(xiàn)有標準中,偽類包括:
:first-child
點我看手冊,應(yīng)用第一個子元素:link
點我看手冊,應(yīng)用未訪問過的鏈接:visited
點我看手冊,應(yīng)用已訪問過的鏈接:hover
點我看手冊,應(yīng)用鼠標指針懸浮的元素:active
點我看手冊,應(yīng)用活動的鏈接:focus
點我看手冊,應(yīng)用聚焦的輸入元素:lang
點我看手冊,偽類將應(yīng)用于元素帶有指定lang的情況,不常用什么是偽元素呢?
偽元素是創(chuàng)造文檔樹之外的對象。例如文檔不能提供訪問元素內(nèi)容第一字或者第一行的機制。偽元素還提供一些在源文檔中不存在的內(nèi)容分配樣式,例如:before
和:after
能夠訪問產(chǎn)生的內(nèi)容。偽元素的內(nèi)容實際上和普通DOM元素是相同的,但是它本身只是基于元素的抽象,并不存在于文檔中,所以叫偽元素。
CSS的現(xiàn)有標準中,偽元素包括:
:first-letter
點我看手冊,偽元素的樣式將應(yīng)用于元素文本的第一個字(母):first-line
點我看手冊,偽元素的樣式將應(yīng)用于元素文本的第一行:before
點我看手冊,在元素內(nèi)容的最前面添加新內(nèi)容:after
點我看手冊,在元素內(nèi)容的最后面添加新內(nèi)容首先說一下偽類和偽元素的相同之處,
偽類和偽元素都不出現(xiàn)在源文件和文檔樹中。也就是說在html源文件中是看不到偽類和偽元素的。
他們的不同之處,
偽類其實就是基于普通DOM元素而產(chǎn)生的不同狀態(tài),他是DOM元素的某一特征。偽元素能夠創(chuàng)建在DOM樹中不存在的抽象對象,而且這些抽象對象是能夠訪問到的。
一句話總結(jié)不同之處就是,偽元素產(chǎn)生新對象,在DOM樹中看不到,但是可以操作;偽類不產(chǎn)生新的對象,僅是DOM中一個元素的不同狀態(tài);
:before
和:after
使用場景現(xiàn)在在一些主流的css框架中,比如Bootstrap,Foundation等中,對:before
及:after
的使用較多,而且這兩個偽元素在一些特定場景下的確有許多妙用。
demo1是一個專門介紹使用:before
及:after
的博文,可以學(xué)習(xí)下。
下面,說一下我之前使用:before
及:after
的一個場景。
現(xiàn)在我們需要使用純CSS做一個下圖中的鏤空箭頭符號,
對應(yīng)的html代碼如下,
<div class="arrow arrow-top"></div>
<div class="arrow arrow-right"></div>
<div class="arrow arrow-bottom"></div>
<div class="arrow arrow-left"></div>
樣式如下,
div.arrow:before, div.arrow:after {
content: ' ';
height: 0;
width: 0;
top: 100px;
left: 255px;
position: absolute;
border: 10px solid transparent;
}
div.arrow-top:before {
border-bottom-color: #fff;
z-index: 2;
top: 102px;
}
div.arrow-top:after {
border-bottom-color: #333;
z-index: 1;
}
div.arrow-right:before {
border-left-color: #fff;
z-index: 2;
left: 297px;
top: 104px;
}
div.arrow-right:after {
border-left-color: #333;
z-index: 1;
left: 300px;
top: 104px;
}
div.arrow-bottom:before {
border-top-color: #fff;
top: 107px;
left: 330px;
z-index: 2;
}
div.arrow-bottom:after {
border-top-color: #333;
top: 110px;
left: 330px;
z-index: 1;
}
div.arrow-left:before {
border-right-color: #fff;
top: 103px;
left: 355px;
z-index: 2;
}
div.arrow-left:after {
border-right-color: #333;
top: 103px;
left: 352px;
z-index: 1;
}
其實原理很簡單,
設(shè)置
.arrow
屬性的:before
和:after
的border
屬性為10px
,顏色為透明的。然后將:before
和:after
中的任意一層的border-color
設(shè)置為可辨識的,然后使用z-index
值較高的層遮蓋z-index
值較低的層,通過微調(diào)top
和left
的值達到目的。
這里我們當(dāng)然可以通過一些美化的手段,使得我們的箭頭看起來更加好看一點,比如像下面這樣,
更多建議: