美文网首页
CSS中变换背景保持内容的实现方案

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

作者: 科研者 | 来源:发表于2017-08-09 13:50 被阅读0次

    在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中特殊效果的实现方案

    相关文章

      网友评论

          本文标题:CSS中变换背景保持内容的实现方案

          本文链接:https://www.haomeiwen.com/subject/mtofrxtx.html