CSS伪:溢出后

时间:2018-07-21 04:06:13

标签: css css3 flexbox css-animations

我想在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

3 个答案:

答案 0 :(得分:2)

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

在这里,我组合了transfrom值的scaleX()translateX(),其中 scaleX 将设置其宽度,而 translateX 将其水平位置

请注意,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(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>


堆栈代码段-使用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>

答案 1 :(得分:0)

与其为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>

答案 2 :(得分:0)

您还可以使用一个元素和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>