CSS中變換背景保持內容的實現方案

在CSS中經常會用到對一個元素進行變換(Transform)但希望元素的內容保持不變的效果;但當我們對元素進行變換時,得到的效果是:不但背景被變換了,而且內容也被變換了;示例如下:

以skewX()變換為例,假設有以下元素:
HTML結構:

<p>
    我是內容
</p>

css樣式:

p {
    display: inline-block;
    border-color: red;
    border-width:1px;
    border-style: solid;
}

效果:

示例效果.png

如果對這個元素使用skewX()變換,則會得到如下效果:
CSS樣式:

transform: skewX(45deg);

效果:

示例效果-變換.png

從效果中可以看出,不僅元素的背景被變換了,而且里面的內容也被變換了,然而,在很多場景下我們只希望變換背景,內容保持不變;

若要解決這個問題,也有多種方案可選(推薦方案3喲),如下:

方案1:外套元素

原理:

在變換時,為了把背景樣式與元素內容分離,可以把目標元素嵌入在一個容器元素內,比如div元素,然后把目標元素的背景樣式移動到容器元素上,使容器元素僅負責背景樣式(稱僅負責樣式的元素為樣式元素),目標元素僅負責內容;然后對樣式元素進行變換,再對目標元素進行反向變換,這樣便實現了變換了背景樣式,而又還原了內容;

原理演示:

  1. 給目標元素添加一個容器元素作為樣式元素;
    ** HTML結構:**

    <div>
        <p>
            我是內容
        </p>
    </div>
    
  2. 把目標元素的背景樣式移動到容器元素上;
    示例效果:

    外套元素.png

    注意:
    虛線框只是用來標識元素的存在,并不表示元素的樣式;

  3. 對容器元素應用變換;
    CSS樣式:

    transform: skewX(45deg);
    

    示例效果:

    外套元素-變換.png

  4. 對目標元素應用反向變換;
    CSS樣式:

    transform: skewX(-45deg);
    

    示例效果:

    外套元素-糾正.png

此方案優點:

  1. 原理直觀,易理解;
  2. 可以實現任意多樣式及內容的分離;
  3. 需要對目標內容再進行反向變換;(有此變換操作是不可逆的,所以反向變換會可能不能還原效果;)

此方案缺點:

  1. 添加了較多冗余的元素;

方案2:內嵌元素

原理:

與外套元素的方案類似,只是把樣式元素插入到了目標元素里面,作為了目標元素的子元素;這樣,在對樣式元素進行變換時,不會影響到目標元素的內容,從而不用使用反向變換;

原理演示:

  1. 給目標元素添加一個子元素作為樣式元素;
    ** HTML結構:**

    <p>
        <span></span>
        我是內容
    </p>
    
  2. 把目標元素的背景樣式移動到樣式元素上;
    示例效果:

    內嵌元素.png

    注意:

    1. 虛線框只是用來標識元素的存在,并不表示元素的樣式;
    2. 如果樣式元素遮擋了目標元素的內容,則需要給樣式元素設置合適的層疊級別z-index;
  3. 對樣式元素應用變換;
    CSS樣式:

    transform: skewX(45deg);
    

    示例效果:

    內嵌元素-變換.png

此方案優點:

  1. 原理直觀,易理解;
  2. 可以實現任意多樣式及內容的分離;
  3. 不用對目標內容再進行反向變換;

此方案缺點:

  1. 添加了較多冗余的元素;

方案3:前后偽元素

原理:

與內嵌元素方案的原理一樣,所不同的是:本方案采用偽元素::before或者::after來作為樣式元素,而不是另外插入額外的元素;

原理演示:

以::before偽元素為例:

  1. 把目標元素的樣式應用到其偽元素::before上;
    ** CSS樣式:**

    p::before {
        border-color: red;
        border-width:1px;
        border-style: solid;
    }
    
  2. 調整::before偽元素的盒子使其與目標元素盒子重疊;
    因為在::before和::after偽元素選擇器中必須定義content屬性,所以需要為::before選擇器中設置值為空字符串的content屬性;
    另外,因為瀏覽器會為這2個偽元素選擇器分別生成相應的盒子,并且這些盒子是作為元素的非主盒子,所以為了不影響主盒子(目標元素的內容)的布局,需要:

    1. 讓偽元素脫離正常文檔流;
    2. 讓目標元素的主盒子成偽元素盒子的包含塊;

    所以需要

    1. 給目標元素設置樣式position: relative;
    2. 給偽元素::before設置樣式:
    position: absolute;
    width: 100%;
    height: 100%;
    

    最終,示例代碼如下:
    ** HTML結構:**

    <p>
     我是內容
    </p>
    

    CSS樣式:

    p {
        display: inline-block;
        position: relative;   /*為::before偽元素生成包含*/
    }
    p::before {
        content: '';
        position: absolute;  /*脫離文檔流*/
        width: 100%;
        height: 100%;
        
        /*目標元素的樣式*/
        border-color: red;
        border-width:1px;
        border-style: solid;
    }
    

    示例效果:

    偽元素.png

    注意:

    1. 虛線框只是用來標識元素的存在,并不表示元素的樣式;
    2. 如果樣式元素遮擋了目標元素的內容,則需要給樣式元素設置合適的層疊級別z-index;
  3. 對::before偽元素應用變換;
    CSS樣式:

    transform: skewX(45deg);
    

    示例效果:

    偽元素-變換.png

此方案優點:

  1. 原理直觀,易理解;
  2. 不用對目標內容再進行反向變換;
  3. 不用添加冗余元素;

此方案缺點:

  1. 只能把樣式及內容分離成2個獨立的部分,不對分成3個或者更多的獨立部分;

相關文章:CSS中特殊效果的實現方案

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,814評論 1 92
  • 本文轉載自:眾成翻譯譯者:為之漫筆鏈接:http://www.zcfy.cc/article/239原文:http...
    極樂君閱讀 7,412評論 1 62
  • 一:在制作一個Web應用或Web站點的過程中,你是如何考慮他的UI、安全性、高性能、SEO、可維護性以及技術因素的...
    Arno_z閱讀 1,232評論 0 1
  • 又叫馬兒跑 又叫馬兒不吃草
    林下生風閱讀 1,275評論 7 15
  • "目錄號: HY-14184A GPCR/G Protein- Macitentan丁基類似物是Macitenta...
    莫小楓閱讀 123評論 0 0