浅谈css的伪元素::after和::before && 给伪元素添加点击事件
css中的::after和::before已經(jīng)被大量地使用在我們?nèi)粘i_發(fā)中了,使用他們可以使我們的文檔結(jié)構(gòu)更加簡潔。但是很多人對::after和::before仍不是特別了解,究竟他們是做什么的?如何使用他們?什么時候應(yīng)該使用他們?筆者總結(jié)了一些對偽元素的理解和使用經(jīng)驗。
一、概念:
1.定義
The CSS ::before(::after)pseudo-elementmatches a virtual first(last) child of the selected element. It is typically used to add cosmetic content to an element by using thecontentCSS property. This element is inline by default.
從定義我們知道::before和::after匹配一個虛擬元素,主要被用于為當(dāng)前元素增加裝飾性內(nèi)容的。他顯示的內(nèi)容是其自身的“content”屬性,默認(rèn)是內(nèi)聯(lián)元素。
其實::after和::before被引入css中,最核心的目的,還是為了實現(xiàn)語義化。在我們實際開發(fā)時候經(jīng)常有這樣的經(jīng)歷,為了實現(xiàn)一些效果,在文檔中創(chuàng)建了一些沒有實際內(nèi)容的節(jié)點,或者加入輔助樣式的文本,如:
<style>
ul{
list-style: none;
}
li{
display: inline;
}
</style>
<nav>
<ul>
<li>HTML 5</li>
<li>|</li>
<li>CSS3</li>
<li>|</li>
<li>JavaScript</li>
</ul>
</nav>
顯示的時候是這樣子的:
很明顯,例子中的“|”僅是顯示時候用的間隔符,沒有實際的意義,而他所在的li元素僅是為了裝飾才被創(chuàng)建的,本是不應(yīng)該被創(chuàng)建在文檔內(nèi)的。那么能不能由樣式(css)去創(chuàng)建出節(jié)點把他們代替掉呢?
出于這樣的需求,就誕生了::after和::before,這兩個偽元素相當(dāng)于是對當(dāng)前元素的裝潢,他們并不是節(jié)點,不會出現(xiàn)在dom樹中,但是在顯示上具備節(jié)點的效果。我們使用::after和::before重構(gòu)一下上邊的代碼:
<style>
ul{
list-style: none;
}
li{
display: inline;
}
li:not(:last-child)::after{
content: "|";
}
</style>
<nav>
<ul>
<li>HTML 5</li>
<li>CSS3</li>
<li>JavaScript</li>
</ul>
</nav>
顯示效果沒有變化,但是文檔結(jié)構(gòu)變得清晰了多了。
2.使用
::after和::before的使用很簡單,可以認(rèn)為其所在元素上存在一前一后的兩個的元素,這兩個元素默認(rèn)是內(nèi)聯(lián)元素,但我們可以為其增添樣式。::after和::before使用的時候一定要注意,必須設(shè)置content,否則這兩個偽元素是無法顯示出來的。而content屬性,會作為這兩個偽元素的內(nèi)容嵌入他們中。如果不需要偽元素的內(nèi)容,可以將content設(shè)置為'',但是不設(shè)置的話,偽元素就會無效。如:
<style>
p:before{
content: "H";
p:after{
content: "d";
}
</style>
<p>ello Worl</p>
顯示為完整的Hello World。
::after和::before是虛擬元素,不會影響真正元素的所在文檔的位置,對:first-child或者:last-child這種偽類選擇不會造成影響。
3.操作
::after和::before是虛擬節(jié)點,而不是正在的節(jié)點,不在documont里面找到對應(yīng)Node對象,在之前的例子中,我們執(zhí)行下列js代碼:
console.log( document.querySelector("ul").childNodes);
得到的是一個只有3個節(jié)點的NodeList對象,而兩個偽元素并不在對象中。因為::after和::before不是真正的節(jié)點,所以我們?nèi)〔坏剿麄?,也不發(fā)設(shè)置點擊等用戶事件。::after和::before雖然是不能設(shè)置事件,但還會捕獲用戶事件,并把事件“冒泡”到偽元素所在的元素上。之所以“冒泡”二字加了引號,是因為他不是真的冒泡,更準(zhǔn)確的說::after和::before幫所在元素去捕獲去事件,事件的srcElement對象是偽元素所在的元素,而不是偽元素本身。
document不能獲取到::after和::before所對應(yīng)的節(jié)點對象,但是可以通過css的接口獲取其樣式屬性,如:
window.getComputedStyle(
document.querySelector('li'), ':before'
)
返回是個CSSStyleDeclaration對象,可以獲取當(dāng)前的style值。
另外,content屬性京城配合attr()函數(shù)使用,attr()函數(shù)用來獲取html元素指定屬性的值,eg:
.wcs:before{
content:attr(title);
color:red;
}
<div class="wcs" title="第五部分">
王船山的美學(xué)思想
</div>
二、分享一些::after和::before使用的經(jīng)驗
以下例子多數(shù)是在特定平臺上使用過的,未做兼容處理,建議在chrome下瀏覽
1.間隔符用法
如文章最開始的例子,使用::after偽元素做間隔符,并使用偽類:not排除掉最后一個元素。
例子
2.做border三角圖標(biāo)
很多開發(fā)者都用過border做的三角圖標(biāo),本身三角符號就不屬于文檔,使用偽元素做三角符最合適了。
例子
3.字符圖標(biāo)
最近筆者在開發(fā)微信小程序,因為微信小程序不支持svg和背景圖,于是筆者大量使用字符圖標(biāo),感覺字符圖標(biāo)非常方便,就是受設(shè)備系統(tǒng)字體庫限制。
例子
4.webfont的圖標(biāo)
現(xiàn)在webfont圖標(biāo)的最佳實踐就是使用i標(biāo)簽和::after或者::before,實現(xiàn)這種圖標(biāo)最佳實踐的工具非常多,比如http://fontello.com/,從這個網(wǎng)站我們可以下載svg的圖標(biāo)庫。這種例子太多了,這里就不再列舉。
5.做單位、標(biāo)簽、表單必填標(biāo)準(zhǔn)
筆者一直認(rèn)為表單輸入框的必填標(biāo)記(往往是紅色的“*”字符),不應(yīng)該放到文檔當(dāng)中,使用::before可以很優(yōu)雅地解決這個問題(其實就是字符圖標(biāo)的進(jìn)一步應(yīng)用)。
對于單位和前(后)置標(biāo)簽,也可以這樣做。但是多數(shù)情況下不推薦這種做法,因為單位和標(biāo)簽應(yīng)該是文檔的一部分。
例子
6.做一些效果
可以參考《理解偽元素 :before 和 :after》這篇文章的效果,筆者曾經(jīng)在實際項目中使用過“迷人的陰影”效果,也曾在微場景開發(fā)中實現(xiàn)過一些類似的動畫。
例子
7.實現(xiàn)一些標(biāo)簽對placeholder的支持
只有幾個標(biāo)簽支持placeholder,而且如<input type='date' />雖然是input但是也不支持。使用::before可以讓一部分標(biāo)簽也實現(xiàn)對placeholder屬性的支持。
例子
8.實現(xiàn)文字圖片居中對齊
優(yōu)雅地實現(xiàn)張鑫旭老師的inline-box居中方法,使用一個高度為100%的::before將自身的對齊線移動到自己的中線,這樣里面的所有內(nèi)聯(lián)元素都居中對齊了。
例子
9.清除浮動
即對浮動盒子的父元素設(shè)置:after產(chǎn)生一個偽元素,用這個偽元素清除浮動,這樣就不需要在浮動元素后面新增一個空元素了。這個很常用,bootstrap的clearfix類就是使用這個方法。
例子
10.使用pointer-events消除偽元素事件
之前提到過,偽元素::after和::before會替所在元素捕獲用戶事件,有時候這并非我們想要的,因為這樣會影響被::after和::before覆蓋的子節(jié)點或者兄弟節(jié)點捕獲用戶事件。
那么如何給偽元素添加點擊事件?
經(jīng)過思考及查找相應(yīng)的資料后,整理初2種方式,記錄一下:
一、給元素設(shè)置pointer-events:none.然后給偽元素的pointer-events:auto;此時我們把點擊元素的事件就取消了。點擊偽元素的時候,就可以綁定相應(yīng)的事件了。
二、第二種是:通過子元素的事件冒泡原理,在子元素事件處理結(jié)束后return false,告知父元素事件處理完畢。這樣只就屏蔽了父元素接收事件,然后:after偽元素是懸浮在子元素上面的,故點擊偽元素的時候觸發(fā)父元素事件。
例子
所有例子的源碼在https://github.com/laden666666/css-before-and-after-test
簡單就分享這么多,總之使用偽元素的核心是更利于語義化,這是我們活用::after和::before的前提,否則就是胡亂使用了??傮w可以分為四種用法:
1.用css創(chuàng)建裝飾性元素
2.用css創(chuàng)建用于布局的元素,實現(xiàn)特殊布局的特殊需要
3.做顯示圖標(biāo)的實現(xiàn)手段
4.配合attr顯示屬性值
三、:before和::before是什么區(qū)別
解答要點
相同點
都可以用來表示偽類對象,用來設(shè)置對象前的內(nèi)容
:befor和::before寫法是等效的
不同點
:befor是Css2的寫法,::before是Css3的寫法
:before的兼容性要比::before好 ,不過在H5開發(fā)中建議使用::before比較好
加分項
偽類對象要配合content屬性一起使用
偽類對象不會出現(xiàn)在DOM中,所以不能通過js來操作,僅僅是在 CSS 渲染層加入
偽類對象的特效通常要使用:hover偽類樣式來激活
test:hover::before { /* 這時animation和transition才生效 */ }
參考:
http://www.webhek.com/pseudo-element/
http://www.cnblogs.com/ys-ys/p/5092760.html
https://developer.mozilla.org/en-US/docs/Web/CSS/::after
https://blog.csdn.net/yangxiaoyanger/article/details/79712180
--------------------- 本文來自 馬大頭 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/w405722907/article/details/79446038?utm_source=copy
總結(jié)
以上是生活随笔為你收集整理的浅谈css的伪元素::after和::before && 给伪元素添加点击事件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Collider Collision 区
- 下一篇: PCB板中的"假八层"