使用transform属性进行多个CSS关键帧动画无法正常工作

31

在使用 CSS关键帧动画 时,我发现当我给一个元素两个动画效果时,例如:

.element {
    animation: animate1 1000ms linear infinite,
               animate2 3000ms linear infinite;
}
如果两个动画都只使用transform属性进行动画,那么只有最后一个会通过层叠触发。但是,如果@keyframes动画分别使用了margindisplay或其他css属性,而另一个使用了transform,则它们都会触发。
在此处查看相关代码的CodePen示例CSS:
@keyframes move {
    0%, 100% { transform: translateX(0px); }
    50% { transform: translateX(50px); }
}
@keyframes skew {
    0%, 100% { transform: skewX(0deg); }
    50% { transform: skewX(15deg); }
}
@keyframes opacity {
    0%, 100% { opacity: 1; }
    50% { opacity: .25; }
}

.taco {
    animation: skew 2000ms linear infinite,
               opacity 4000ms linear infinite;
}

在上述情况下,它们都会触发

.burger {
    animation: skew 2000ms linear infinite,
               move 4000ms linear infinite;
}

为什么只有最后一个触发器被触发(通过级联)- 为什么?

有没有一种不使用js的解决方案?或者这是不可行的?示例非常简单,我知道我可以将动画合并成一个动画而不必声明两个,但这是我正在处理的更复杂动画的测试。

谢谢

3个回答

44

在同一个元素上,您不能多次使用相同的属性进行动画处理(例如 transform 属性),最后一次动画将覆盖其他动画。

您应该将目标元素放置在一个 div 中,对 div 应用一个 transform 动画效果,而对目标元素应用另一个 transform 动画效果......

.div_class
{
    animation:animate1 1000ms linear infinite;
}

.element
{     
   animation:animate2 3000ms linear infinite;
}

感谢您提出将其包装在 div 中的想法,这两个变换动画需要不同的时间。 - Danferth
在同一个元素上不能对相同的属性进行多次动画。虽然这看起来并不完全准确,参见:http://jsfiddle.net/j83m5ha5/4/。在这个例子中,相同的元素在同一类上链接了相同的属性。为什么这样能行,但是使用transform就不行呢? - Stephan Muller
@StephanMuller,我已经检查了你的动画,第二个动画(out)正在覆盖第一个动画(in),只需增加第一个动画的持续时间,比如将其设置为10秒,并查看效果,你会发现它是一个1分钟的动画,因为第二个动画正在覆盖第一个动画。 - Scarecrow

11

出于同样的原因,

transform: skewX(45deg);
transform: translateX(4em);

不会扭曲元素,只会移动它。如果您想同时扭曲和移动它,则需要将它们链接起来 transform: skewX(45deg) translateX(4em)

您需要像这样做:

@keyframes t {
    25% { transform: skewX(15deg); }
    50% { transform: skewX(0deg) translateX(50px); }
    75% { transform: skewX(15deg); }
}

您不需要显式指定0%100%的关键帧-它们将自动生成-请参见CSS动画规范

然后您可以使用:

animation: t 4000ms linear infinite,
        opacity 4000ms linear infinite;

还有一件事情需要注意: skewX(angleValue) translateX(lengthValue) 恰好等同于 translateX(lengthValue) skewX(angleValue)。然而,大多数情况下,应用变换的顺序是有影响的。对于skewX(angleValue) translateY(lengthValue)translateY(lengthValue) skewX(angleValue),你会得到不同的结果。


1

@StephanMuller的jsfiddle基本上就是答案,那个语法对我很有用。 http://jsfiddle.net/j83m5ha5/4

div {
background:green;
width:100px;
height:100px;
-webkit-animation: in 2s 200ms  forwards, out 1s 2200ms forwards;
}

我相信提问者的目的是为了标准化他的动画并在需要时应用它们,以下是我课程中最近的练习代码:https://jsfiddle.net/kgLc56w4/

#b15{
top:200px;
left:200px;
background:#ff3399;
-webkit-animation: r4 ease-in-out 2s forwards 24s, s4 ease-in-out 2s forwards 30s;
}

每个块只能朝一个方向移动,所以我只使用了8个简单的动画,而不是制作15个动画。我知道这可能可以更简单地完成,但这不是练习的重点。
不过,我在最后第15个元素上使用了Stephan的语法来再次移动它,它有效了。
你只需要注意时间,对于Stephen的情况,如果你增加了第一个(in)动画的持续时间,就需要增加第二个(out)的延迟时间。
例如:
-webkit-animation: in 20s 200ms  forwards, out 1s 20200ms forwards;

希望这有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接