css僞元素:before和:after用法詳解

css的僞元素,之因此被稱爲僞元素,是由於他們不是真正的頁面元素,html沒有對應的元素,可是其全部用法和表現行爲與真正的頁面元素同樣,能夠對其使用諸如頁面元素同樣的css樣式,表面上看上去貌似是頁面的某些元素來展示,其實是css樣式展示的行爲,所以被稱爲僞元素。以下圖,是僞元素在html代碼機構中的展示,能夠看出沒法僞元素的結構沒法審查。css

css有一系列的僞元素,如:before,:after,:first-line,:first-letter等,本文就詳述一下:before和:after元素的使用html

1、僞元素:before和:after用法

這個兩個僞元素在真正頁面元素內部以前以後添加新內容(固然了,能夠對僞元素應用定位能夠置於任何位置)。能夠用如下例子來講明:前端

<p>wonyun!</p>
    <style>
        p:before{content: "hello "}
        p:after{content: "you are handsome!"}
    </style>

上面例子從技術角度看,等價於下面的html結構:web

<p>
        <span>hello </span>
        wonyun!
        <span> you are handsome!</span>
    </p>

由此可知:僞元素:before和:after添加的內容默認是inline元素;這個兩個僞元素的content屬性,表示僞元素的內容,設置:before和:after時必須設置其content屬性,不然僞元素就不起做用。那麼問題來了,content屬性的值能夠有哪些內容呢,具體有如下幾種狀況:segmentfault

  • 字符串,字符串做爲僞元素的內容添加到主元素中app

    注意:字符串中如有html字符串,添加到主元素後不會進行html轉義,也不會轉化爲真正的html內容顯示,而是會原樣輸出dom

  • attr(attr_name), 僞元素的內容跟主元素的某個屬性值進行關聯,及其內容爲主元素的某指定屬性的值學習

    好處:能夠經過js動態改變主元素的指定屬性值,這時僞元素的內容也會跟着改變,能夠實現某些特殊效果,如圖片加載失敗用一段文字替換。url

  • url()/uri(), 引用外部資源,例如圖片;spa

  • counter(), 調用計數器,能夠不使用列表元素實現序號問題。


2、:before和:after特色

上面說了,僞元素是經過樣式來達到元素效果的,也就是說僞元素不佔用dom元素節點,引用:before,:after僞元素妙用裏面總結的,:before和:after僞元素的主要特色以下:

  • 僞元素不屬於文檔,因此js沒法操做它

  • 僞元素屬於主元素的一部分,所以點擊僞元素觸發的是主元素的click事件

  • 原文說塊級元素纔能有:before, :after,實際上是不妥的,大部分行級元素也能夠設置僞元素,可是像img可替換元素,由於其外觀和尺寸有外部資源決定,那麼若是外部資源正確加載,就會替換掉其內部內容,這時僞元素也會被替換掉,可是當外部資源加載失敗時,設置的僞元素是能夠起做用的。

基於僞元素的特色能夠知道其優缺點,也引用別人文章的話:

  • 優勢

    • 減小dom節點數
    • 讓css幫助解決部分js問題,讓問題變得簡單
  • 缺點

    • 不利於SEO
    • 沒法審查元素,不利於調試

3、:before和:after常見使用場景

  1. 清除浮動
清除浮動是前端最多見的問題,有一種作法是使用一個空的頁面元素如div來清除浮動,可是這種作法增長毫無語義的頁面元素,並且佔用dom節點。更可取的作法是利用僞元素來清除浮動:
<div class="l-form-row">
                <div class="l-form-label"></div>
                ....
            </div>
            <style>
                .l-form-row:after {
                    clear: both;
                    content: "\0020";
                    display: block;
                    height: 0;
                    overflow: hidden
                }
            </style>

這樣,class=l-form-row的元素內部任何浮動都能清除掉,不用額外添加無心義的元素。

  1. 利用attr()來實現某些動態功能

在頁面中常見這種問題,頁面上加載的圖片在沒法加載時會顯示一個破損圖片,直接影響頁面的美觀;

那麼能夠經過僞元素配合樣式可以讓未加載的圖片看起來真的像破裂的效果,以下圖所示:

<img>是一個替換元素,其外觀和尺寸是由外部資源來決定的,當外部圖片資源加載失敗時其會顯示破裂圖片和alt文字,尺寸僅由其自身內容決定。這時<img>元素可使用僞元素:before:after,由於其元素內容沒有被替換;利用attr()來獲取圖片alt屬性值做爲僞元素:aftercontent內容來替換img的內容,並運用適當的樣式從而完成:圖片加載成功時顯示正常的圖片,加載失敗時顯示圖片破裂效果的樣式,具體代碼參考:

img{
            min-height: 50px;
           position: relative;
        }
        img:before: {
             content: " ";
             display: block;
            position: absolute;
            top: -10px;
            left: 0;
            height: calc(100% + 10px);
            width: 100%;
            backgound-color: rgb(230, 230,230);
            border: 2px dotted rgb(200,200,200);
            border-radius: 5px;
        }
        img: {
            content: '\f127" " Broken Image of " attr(alt);
            display: block;
            font-size: 16px;
            font-style: normal;
            font-family: FontAwesome;
            color: rgb(100,100,100)
            position: absolute;
            top: 5px;
            left: 0;
            width: 100%;
            text-align: center;
        }
  1. 與counter()結合實現序號問題,而不用使用列表元素。具體還要結合css的 counter-increment 和 counter-reset 屬性的用法 。

代碼以下:

<h2></h2>
        <h2></h2>
        <style>
            body {counter-reset:section;}
            h2:before { 
                counter-increment: section; 
                content: "Chapter"  counter(section) ".";
            }
        </style>

結果以下:

  1. 特效使用

利用這兩個僞元素,能夠實現各類效果,如放大鏡、叉叉、箭頭、三角符等,也可輕易實現以下效果

代碼實現以下:

a {
        position: relative;
        display: inline-block;
        outline: none;
        text-decoration: none;
        color: #000;
        font-size: 32px;
        padding: 5px 10px;
        }

        a:hover::before, a:hover::after { position: absolute; }
        a:hover::before { content: "\5B"; left: -20px; }
        a:hover::after { content: "\5D"; right:  -20px; }

代碼實現以下:

table{overflow: hidden;}
        td, th{
            padding: 10px;
            position: relative;
            outline: 0;
        }
        td:hover::after,
        th:hover::after { 
              content: '';  
              background-color: lightblue;
              position: absolute;  
              left: 0;
              height: 10000px;
              top: -5000px;
              width: 100%;
              z-index: -1;
        }

        td:hover::before {
              background-color: lightblue;
              content: '';  
              height: 100%;
              top: 0;
              left: -5000px;
              position: absolute;  
              width: 10000px;
              z-index: -1;
        }


具體代碼:

.empty__bg {
                display: inline-block;
                width: 95px;
                height: 92px;
                background: url(http://7tszky.com1.z0.glb.clouddn.com/FvD_sYY4Fmp_yKS0E07H-5jhuKTB) no-repeat;
                background-size: 95px 92px;
                position: relative;
                margin-bottom: 16px;/*注意這裏須要留好位置放置after元素(它是absolute進去的)*/
            }
            .empty__bg:after {
                content: "暫無學習計劃";
                display: block;
                font-size: 14px;
                line-height: 24px;
                text-align: center;
                width: 100%;
                color: #909090;
                position: absolute;
                top: 100%;
                left: 0;
            }
        }


上述能夠實現擴大可點擊區域,這對應手機用戶來講更加友好一些,不然用戶點擊不會觸發相應的事件;具體代碼實現以下:

.play-cover {position: relative}
        .play-cover:before{
            content: "";
            display: block;
            position: absolute;
            width: 0;
            height: 0;
            border-left: 8px solid white;
            border-top: 5px solid transparent;
            border-bottom: 5px solid transparent;
            margin-left: 9px;
            margin-bottom: 7px;
            z-index: 5;
        }
        .play-cover:after{
            content: '';
            display: block;
            position: absolute;
            width: 20px;
            height: 20px;
            border: 2px solid white;
            background: rgba(0, 0, 0, .6);
            border-radius: 12px;
            background-clip: padding-box;
        }

CSS美化radio和checkbox的樣式magic-check,就是利用僞元素:before和:after來實現的;
具體是爲每一個真正的表單元素radio和checkbox搭配一個label,而後隱藏真正的radio和checkbox,label元素單擊的時候隱藏的radio或者checkbox其實是處於checked狀態,這跟label的具體用法有關;利用label的僞元素:before和:after來實現美化radio和checkbox。

下面是checkbox的美化的css代碼:

.magic-checkbox {
              position: absolute;
              display: none;  //先隱藏真正的checkboxbox
         }
         .magic-checkbox + label {//爲與checkbox搭配的label使用樣式
              position: relative; //相對定位,方便其內容的僞元素進行定位
              display: block; //塊元素
              padding-left: 30px;
              cursor: pointer;
              vertical-align: middle; 
         }
        .magic-checkbox + label:before { //label添加:before僞元素,用於生成一個帶邊界的正方形,模擬複選框的輪廓
                position: absolute;
                top: 0;
                left: 0;
                display: inline-block;
                width: 20px;
                height: 20px;
                content: '';
                border: 1px solid #c0c0c0; 
                border-radius: 3px; 
            }
            //爲checkbox添加:after僞元素,做用是生成一個√圖形,模擬checkbox選中狀態,未選中狀態下會被隱藏
            .magic-checkbox + label:after {
                  top: 2px;
                  left: 7px;
                  box-sizing: border-box;
                  width: 6px;  //實現√圖形很簡單:設置一個長方形,去掉其上邊界和左邊界,剩下的2個邊界旋轉45度就獲得√形狀
                  height: 12px;
                  transform: rotate(45deg);
                  border-width: 2px;
                  border-style: solid;
                  border-color: #fff;
                  border-top: 0;
                  border-left: 0;
                  position: absolute;
                  display: none; //√形狀先隱藏
                  content: '';
              }
            //單擊label,隱藏的checkbox爲checked狀態,這時設置checked狀態下搭配label的:before僞元素背景和邊界顏色
             .magic-checkbox:checked + label:before {
                    animation-name: none; 
                    border: #3e97eb;
                    background: #3e97eb; 
                }
            //checked狀態的checkbox搭配的label僞元素:after此時設置顯示,那麼√就顯示出來了
             .magic-checkbox:checked + label:after {
                  display: block; 
             }

利用:before和:after能輕易實現美化的radio和checkbox


參考文檔

  1. :before,:after僞元素妙用
  2. 前端開發中的一些黑魔法Pt1
  3. 你所不知的 CSS ::before 和 ::after 僞元素用法
  4. 純CSS製做各類圖形(多圖預警)
相關文章
相關標籤/搜索