CSS中变换背景保持内容的实现方案

在CSS中经常会用到对一个元素进行变换(Transform)但希望元素的内容保持不变的效果;但当我们对元素进行变换时,得到的效果是:不但背景被变换了,而且内容也被变换了;示例如下:

以skewX()变换为例,假设有以下元素:
HTML结构:

我是内容

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结构:**

    我是内容

  2. 把目标元素的背景样式移动到容器元素上;
    示例效果:

    CSS中变换背景保持内容的实现方案_第1张图片
    外套元素.png

    注意:
    虚线框只是用来标识元素的存在,并不表示元素的样式;

  3. 对容器元素应用变换;
    CSS样式:

    transform: skewX(45deg);
    

    示例效果:

    外套元素-变换.png

  4. 对目标元素应用反向变换;
    CSS样式:

    transform: skewX(-45deg);
    

    示例效果:

    外套元素-纠正.png

此方案优点:

  1. 原理直观,易理解;
  2. 可以实现任意多样式及内容的分离;
  3. 需要对目标内容再进行反向变换;(有此变换操作是不可逆的,所以反向变换会可能不能还原效果;)

此方案缺点:

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

方案2:内嵌元素

原理:

与外套元素的方案类似,只是把样式元素插入到了目标元素里面,作为了目标元素的子元素;这样,在对样式元素进行变换时,不会影响到目标元素的内容,从而不用使用反向变换;

原理演示:

  1. 给目标元素添加一个子元素作为样式元素;
    ** HTML结构:**

    我是内容

  2. 把目标元素的背景样式移动到样式元素上;
    示例效果:

    CSS中变换背景保持内容的实现方案_第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结构:**

    我是内容

    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;
    }
    

    示例效果:

    CSS中变换背景保持内容的实现方案_第3张图片
    伪元素.png

    注意:

    1. 虚线框只是用来标识元素的存在,并不表示元素的样式;
    2. 如果样式元素遮挡了目标元素的内容,则需要给样式元素设置合适的层叠级别z-index;
  3. 对::before伪元素应用变换;
    CSS样式:

    transform: skewX(45deg);
    

    示例效果:

    伪元素-变换.png

此方案优点:

  1. 原理直观,易理解;
  2. 不用对目标内容再进行反向变换;
  3. 不用添加冗余元素;

此方案缺点:

  1. 只能把样式及内容分离成2个独立的部分,不对分成3个或者更多的独立部分;

相关文章:《 CSS中特殊效果的实现方案》

你可能感兴趣的:(CSS中变换背景保持内容的实现方案)