首页 > 解决方案 > (css)在@keyframe中改变百分比使变换动画重复

问题描述

所以我有一个简单的按钮,通过使用 ::after 和变换来运行具有闪亮效果的按钮。

.shiny {
  background-color: #000000;
  padding: 10px;
  color: white;
  border-radius: 5px;
  position: relative;
}

@keyframes sheen {
/*   make the sheen run forward for 1.5s then back for the last 0.5s */
      75% {
    transform: rotateZ(60deg) translate(1em, -9em);
  }  

}

.shiny::after {
  content: '';
  position: absolute;
  top: -50%;
  right: -50%;
  bottom: -50%;
  left: -50%;
  background: linear-gradient(to bottom, rgba(229, 172, 142, 0), rgba(255,255,255,0.5) 50%, rgba(229, 172, 142, 0));
  transform: rotateZ(60deg) translate(-5em, 7.5em);
}

.shiny:hover::after, .shiny:focus::after {
  animation: sheen 2s;
}
<button class="shiny">Shiny Button</button>

在原始代码中,@keyframe 中的百分比为 100%,“光泽”效果正好在 2 秒内向前运行。这里我将百分比设置为低于 100%(例如 75%),效果将向前运行 75% 的动画持续时间,然后向后运行最后 25%。这种行为与“转换”属性有什么关系?谁能给我解释一下

标签: css-transforms

解决方案


事实上,动画不会重复。动画开始和结束。当您没有定义要做什么动画时,它只是模拟为其提供参考值的属性。

在这里,您基本上通过给出具体属性来定义那个时刻,例如它在 2 秒的第 75% 时刻的位置、它将是什么颜色、它的不透明度是什么。但是从 75.1% 开始,在动画完成 (100%) 之前,您还没有定义要做什么。

如果CSS 动画没有在帧的任何时刻定义,它们接受引用它的父属性。

.dummy {
  animation: dummy ... ... ...;
  opacity: .75;
}

@keyframes dummy {
   50% {
     opacity: .5;
   }
}

.75在上面的示例中,元素将分别以.50和的不透明度进行动画处理.75

如果我们没有指定 property opacity: .75;,它也会使用默认值对1.0,.50和动画进行动画处理。1.0

你也可以想象相反的情况。

换句话说,如果我定义了元素最初在动画中的位置,并且该位置与它实际引用的值不同,则元素将通过从我定义的点移动到参考值来进行动画处理。

这是一个简单的例子,

p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }
}
<p>The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.</p>

回到您问题中的示例,定义它应该在75%和之间表现出相同的行为就足够了100%。这是示例;

.shiny {
  background-color: #000000;
  padding: 10px;
  color: white;
  border-radius: 5px;
  position: relative;
}

@keyframes sheen {
/*   make the sheen run forward for 1.5s then back for the last 0.5s */
      75%, 100% {
    transform: rotateZ(60deg) translate(1em, -9em);
  }  

}

.shiny::after {
  content: '';
  position: absolute;
  top: -50%;
  right: -50%;
  bottom: -50%;
  left: -50%;
  background: linear-gradient(to bottom, rgba(229, 172, 142, 0), rgba(255,255,255,0.5) 50%, rgba(229, 172, 142, 0));
  transform: rotateZ(60deg) translate(-5em, 7.5em);
}

.shiny:hover::after, .shiny:focus::after {
  animation: sheen 2s;
}
<button class="shiny">Shiny Button</button>


推荐阅读