【问题标题】:CSS pseudo :after overflowingCSS 伪:溢出后
【发布时间】:2018-07-21 19:28:30
【问题描述】:

我想在 div 中使用模拟边框动画来显示进度。该 div 是一个具有相对位置的 flexbox 元素。我正在添加一个伪元素来为边框底部设置动画。

CSS

       .test {
             display: flex;
             box-sizing: border-box;
             width: 384px;
             border: 1px solid;
             height: 48px;
             position: relative;
        }

        .test:before {
             content: '';
             position: absolute;
             bottom: 0;
             left: 0;
             // width: 100%;
             width: -webkit-fill-available;
             height: 2px;
             background: red;
             animation: running-progress 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
        }

         @keyframes running-progress {
             0% { margin-left: 0px; margin-right: 100%; }
             50% { margin-left: 25%; margin-right: 0%; }
             100% { margin-left: 100%; margin-right: 0; } }

这是一个有问题的代码框:

https://codesandbox.io/s/yopwy5klz

问题

在这个给定的例子中,如何将宽度限制为伪元素不会溢出框的定义宽度?

仅供参考,如果我添加 width: -webkit-fill-available; 它可以正常工作,但我认为这不是正确的解决方案。

这是一个“工作”版本https://codesandbox.io/s/wyp8q26qvk

【问题讨论】:

标签: css flexbox css-animations


【解决方案1】:

由于transform 使用 GPU,您希望将其用于动画,因为它比所有其他属性都使用的基于 CPU 的动画具有更好的性能和更少的延迟。

这里我结合了transfrom 值的scaleX()translateX(),其中scaleX 将设置它的宽度,translateX 将设置它的水平位置。

请注意,transform 从右到左执行其值,因此如果换位,结果会有所不同

堆栈 sn-p - 就像“非工作”一样,当涉及到它的动画方式时,并且没有溢出。

.test {
  display: flex;
  box-sizing: border-box;
  width: 384px;
  border: 1px solid;
  height: 48px;
  position: relative;
}

.test::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  transform: translateX(0%) scaleX(1);
  height: 2px;
  background: red;
  animation: running-progress 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes running-progress {
  0% {
    transform: translateX(0%) scaleX(1);
  }
  50% {
    transform: translateX(12.5%) scaleX(0.75);
  }
  100% {
    transform: translateX(50%) scaleX(0);
  }
}
<div class="test"></div>

堆栈 sn-p - 作为您的“工作”版本,使用 transform

.test {
  display: flex;
  box-sizing: border-box;
  width: 384px;
  border: 1px solid;
  height: 48px;
  position: relative;
}

.test::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  transform: translateX(-50%) scaleX(0);
  height: 2px;
  background: red;
  animation: running-progress 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes running-progress {
  0% {
    transform: translateX(-50%) scaleX(0);
  }
  50% {
    transform: translateX(12.5%) scaleX(.75);
  }
  100% {
    transform: translateX(50%) scaleX(0);
  }
}
<div class="test"></div>

三个注意事项:

  • <div /> 不是自闭合标签,它需要一个开始和结束标签<div></div>

  • 宽度的fill-available 值可以完成这项工作,并且可能是比下面的overflow: hidden 更好的选择(当另一个孩子可能需要溢出时),并且很快就会成为一个选项,尽管它仍然是实验性,不推荐用于生产

  • 有时只需要overflow: hidden,这里适用于您原来的“非工作”示例

    .test {
      display: flex;
      box-sizing: border-box;
      width: 384px;
      border: 1px solid;
      height: 48px;
      position: relative;
      overflow: hidden;
    }
    
    .test::before {
      content: '';
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      height: 2px;
      background: red;
      animation: running-progress 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
    }
    
    @keyframes running-progress {
      0% {
        margin-left: 0px;
        margin-right: 100%;
      }
      50% {
        margin-left: 25%;
        margin-right: 0%;
      }
      100% {
        margin-left: 100%;
        margin-right: 0;
      }
    }
    <div class="test"></div>

【讨论】:

    【解决方案2】:

    您也可以使用一个元素和linear-gradient

    .box {
      position: relative;
      box-sizing: border-box;
      width: 384px;
      height: 48px;
      border: 1px solid;
      background:
        linear-gradient(red,red) bottom/100% 2px no-repeat;
      animation: running-progress 2s cubic-bezier(0.4, 0, 0.2, 1) infinite
    }
    
    @keyframes running-progress {
      0% {
        background-position: bottom left;
        background-size:0% 2px;
      }
      50% {
        background-position: bottom right;
        background-size:70% 2px;
      }
      100% {
        background-position: bottom right;
        background-size:0% 2px;
      }
    }
    <div class="box"></div>

    【讨论】:

      【解决方案3】:

      而不是动画边缘动画leftright属性,并删除伪元素的width: 100%

      .test {
        position: relative;
        box-sizing: border-box;
        width: 384px;
        height: 48px;
        border: 1px solid;
      }
      
      .test::before {
        position: absolute;
        bottom: 0;
        height: 2px;
        background: red;
        animation: running-progress 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
        content: '';
      }
      
      @keyframes running-progress {
        0% {
          left: 0px;
          right: 100%;
        }
        50% {
          left: 25%;
          right: 0%;
        }
        100% {
          left: 100%;
          right: 0;
        }
      }
      <div class="test"></div>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-21
        • 2014-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多