我想在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
答案 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)
与其为left
和right
属性设置动画的边距,而是删除伪元素的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>