css中的::after和::before已經被大量地使用在咱們平常開發中了,使用他們可使咱們的文檔結構更加簡潔。可是不少人對::after和::before仍不是特別瞭解,究竟他們是作什麼的?如何使用他們?何時應該使用他們?筆者總結了一些對僞元素的理解和使用經驗。css
The CSS ::before(::after)
pseudo-element matches a virtual first(last) child of the selected element. It is typically used to add cosmetic content to an element by using the content
CSS property. This element is inline by default.html
從定義咱們知道::before和::after匹配一個虛擬元素,主要被用於爲當前元素增長裝飾性內容的。他顯示的內容是其自身的「content
」屬性,默認是內聯元素。git
其實::after和::before被引入css中,最核心的目的,仍是爲了實現語義化。在咱們實際開發時候常常有這樣的經歷,爲了實現一些效果,在文檔中建立了一些沒有實際內容的節點,或者加入輔助樣式的文本,如:github
<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>
顯示的時候是這樣子的:web
很明顯,例子中的「|」僅是顯示時候用的間隔符,沒有實際的意義,而他所在的li元素僅是爲了裝飾才被建立的,本是不該該被建立在文檔內的。那麼能不能由樣式(css)去建立出節點把他們代替掉呢?chrome
出於這樣的需求,就誕生了::after和::before,這兩個僞元素至關因而對當前元素的裝潢,他們並非節點,不會出如今dom樹中,可是在顯示上具有節點的效果。咱們使用::after和::before重構一下上邊的代碼:bootstrap
<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>
顯示效果沒有變化,可是文檔結構變得清晰了多了。小程序
::after和::before的使用很簡單,能夠認爲其所在元素上存在一前一後的兩個的元素,這兩個元素默認是內聯元素,但咱們能夠爲其增添樣式。::after和::before使用的時候必定要注意,必須設置content,不然這兩個僞元素是沒法顯示出來的。而content屬性,會做爲這兩個僞元素的內容嵌入他們中。若是不須要僞元素的內容,能夠將content設置爲'',可是不設置的話,僞元素就會無效。如:微信小程序
<style> p:before{ content: "H"; p:after{ content: "d"; } </style> <p>ello Worl</p>
顯示爲完整的Hello World。微信
::after和::before是虛擬元素,不會影響真正元素的所在文檔的位置,對:first-child或者:last-child這種僞類選擇不會形成影響。
::after和::before是虛擬節點,而不是正在的節點,不在documont裏面找到對應Node對象,在以前的例子中,咱們執行下列js代碼:
console.log( document.querySelector("ul").childNodes);
獲得的是一個只有3個節點的NodeList對象,而兩個僞元素並不在對象中。由於::after和::before不是真正的節點,因此咱們取不到他們,也不發設置點擊等用戶事件。::after和::before雖然是不能設置事件,但還會捕獲用戶事件,並把事件「冒泡」到僞元素所在的元素上。之因此「冒泡」二字加了引號,是由於他不是真的冒泡,更準確的說::after和::before幫所在元素去捕獲去事件,事件的srcElement對象是僞元素所在的元素,而不是僞元素自己。
document不能獲取到::after和::before所對應的節點對象,可是能夠經過css的接口獲取其樣式屬性,如:
window.getComputedStyle( document.querySelector('li'), ':before' )
返回是個CSSStyleDeclaration對象,能夠獲取當前的style值。
另外,content屬性京城配合attr()函數使用,attr()函數用來獲取html元素指定屬性的值,eg: .wcs:before{ content:attr(title); color:red; } <div class="wcs" title="第五部分"> 王船山的美學思想 </div>
如下例子多數是在特定平臺上使用過的,未作兼容處理,建議在chrome下瀏覽
如文章最開始的例子,使用::after僞元素作間隔符,並使用僞類:not排除掉最後一個元素。
不少開發者都用過border作的三角圖標,自己三角符號就不屬於文檔,使用僞元素作三角符最合適了。
最近筆者在開發微信小程序,由於微信小程序不支持svg和背景圖,因而筆者大量使用字符圖標,感受字符圖標很是方便,就是受設備系統字體庫限制。
如今webfont圖標的最佳實踐就是使用i標籤和::after或者::before,實現這種圖標最佳實踐的工具很是多,好比http://fontello.com/,從這個網站咱們能夠下載svg的圖標庫。這種例子太多了,這裏就再也不列舉。
筆者一直認爲表單輸入框的必填標記(每每是紅色的「*」字符),不該該放到文檔當中,使用::before能夠很優雅地解決這個問題(其實就是字符圖標的進一步應用)。
對於單位和前(後)置標籤,也能夠這樣作。可是多數狀況下不推薦這種作法,由於單位和標籤應該是文檔的一部分。
能夠參考《理解僞元素 :before 和 :after》這篇文章的效果,筆者曾經在實際項目中使用過「迷人的陰影」效果,也曾在微場景開發中實現過一些相似的動畫。
只有幾個標籤支持placeholder,並且如<input type='date' />雖然是input可是也不支持。使用::before可讓一部分標籤也實現對placeholder屬性的支持。
優雅地實現張鑫旭老師的inline-box居中方法,使用一個高度爲100%的::before將自身的對齊線移動到本身的中線,這樣裏面的全部內聯元素都居中對齊了。
即對浮動盒子的父元素設置:after產生一個僞元素,用這個僞元素清除浮動,這樣就不須要在浮動元素後面新增一個空元素了。這個很經常使用,bootstrap的clearfix類就是使用這個方法。
以前提到過,僞元素::after和::before會替所在元素捕獲用戶事件,有時候這並不是咱們想要的,由於這樣會影響被::after和::before覆蓋的子節點或者兄弟節點捕獲用戶事件,使用pointer-events能夠消除這種問題。
全部例子的源碼在https://github.com/laden666666/css-before-and-after-test
簡單就分享這麼多,總之使用僞元素的核心是更利於語義化,這是咱們活用::after和::before的前提,不然就是胡亂使用了。整體能夠分爲四種用法:
1.用css建立裝飾性元素
2.用css建立用於佈局的元素,實現特殊佈局的特殊須要
3.作顯示圖標的實現手段
4.配合attr顯示屬性值
參考:
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
--------------------- 本文來自 馬大頭 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/w405722907/article/details/79446038?utm_source=copy