Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining Multiple CSS Animations

I am trying to chain together 2 CSS animations, see pen: http://codepen.io/jdesilvio/pen/pjwvyO

I have followed the syntax provided in other answers to similar questions, but they don't seem to work correctly:

animation-name: falling, laydown;
animation-duration: 2000ms, 1000ms;
animation-timing-function: ease-in, ease-out;
animation-iteration-count: 1, 1;

It is playing the second animation, then the first and finally the second one again. How can I get it to play the first, then second?

Here is the full code:

<!DOCTYPE html>
<meta charset="utf-8">
<style>

html, body {
  height: 100%;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
}

@keyframes falling {
  0% {
    transform: translate3d(0, -400px, 0);
  }
  100% {
    transform:
      translate3d(0, 40%, 0)
      rotateX(30deg)
      rotateY(0deg)
      rotateZ(60deg);
  }
}

@keyframes laydown {
  0% {
    transform:
      translate3d(0, 40%, 0)
      rotateX(30deg)
      rotateY(0deg)
      rotateZ(60deg);
  }
  100% {
    transform:
      translate3d(0, 40%, 0)
      rotateX(70deg)
      rotateY(0deg)
      rotateZ(80deg);
  }
}

#falling-card-parent {
  height: 150px;
  width: 100px;
  margin: auto;
  perspective: 1000px;
}

#falling-card {
  height: 150px;
  width: 100px;
  background-color: black;
  margin: auto;
  transform:
    translate3d(0, 40%, 0)
    rotateX(70deg)
    rotateY(0deg)
    rotateZ(80deg);
  animation-name:
    falling, laydown;
  animation-duration:
    2000ms, 1000ms;
  animation-timing-function:
    ease-in, ease-out;
  animation-iteration-count:
    1, 1;
}

</style>
<html>
  <body>
    <div id="falling-card-parent">
      <div id="falling-card"></div>
    </div>
  </body>
</html>
like image 961
jdesilvio Avatar asked Oct 08 '15 01:10

jdesilvio


People also ask

Can you have 2 animations CSS?

Setting multiple animation property valuesThe CSS animation longhand properties can accept multiple values, separated by commas. This feature can be used when you want to apply multiple animations in a single rule and set different durations, iteration counts, etc., for each of the animations.

Can you have multiple keyframes CSS?

You can animate multiple properties inside a keyframe rule and use multiple keyframes to specify an element's property values at specific points in time. For example, suppose you have an element that you want to animate from one position to another, horizontally.

What is multi step animation?

That's the concept of multi-step animations in a nutshell: more than one change taking place in the animation from start to finish.

Is CSS animation faster than JavaScript?

CSS has fairly good performance as it offloads animation logic onto the browser itself. This lets the browser optimize DOM interaction and memory consumption and most importantly, uses the GPU to improve performance. On the other hand, Javascript performance can range from reasonably faster to much slower than CSS.


1 Answers

The problem is actually not with the order of the animations but because of how multiple animations on pme element works. When multiple animations are added on an element, they start at the same time by default.

Because of this, both the laydown and falling animations start at the same time but the laydown animation actually completes within 1000ms from the start but the first animation (which is falling) doesn't complete till 2000ms.

The W3C spec about animations also say the following about multiple animations accessing the same property during animation:

If multiple animations are attempting to modify the same property, then the animation closest to the end of the list of names wins.

In the code provided in question, both animations are trying to modify the transform property and the second animation is the closest to the end. So while the second animation is still running (which is, for the first 1000ms) the transform changes are applied as specified in the second animation. During this time the first animation is still running but it has no effect because its values are overwritten. In the 2nd 1000ms (when the second animation has already completed but 1st is still executing), the transforms are applied as directed by the first animation. This is why it looks as if the second animation is running before the first animation and then the first.


To fix this problem, the execution of the second animation should be put on hold (or delayed) until the time the first animation is complete. This can be done by adding a animation-delay (that is equal to the animation-duration of the first animation) for the second animation.

animation-name: falling, laydown;
animation-duration: 2000ms, 1000ms;
animation-delay: 0ms, 2000ms; /* add this */
animation-timing-function: ease-in, ease-out;
animation-iteration-count: 1, 1;

html,
body {
  height: 100%;
}
body {
  display: flex;
  align-items: center;
  justify-content: center;
}
@keyframes falling {
  0% {
    transform: translate3d(0, -400px, 0);
  }
  100% {
    transform: translate3d(0, 40%, 0) rotateX(30deg) rotateY(0deg) rotateZ(60deg);
  }
}
@keyframes laydown {
  0% {
    transform: translate3d(0, 40%, 0) rotateX(30deg) rotateY(0deg) rotateZ(60deg);
  }
  100% {
    transform: translate3d(0, 40%, 0) rotateX(70deg) rotateY(0deg) rotateZ(80deg);
  }
}
#falling-card-parent {
  height: 150px;
  width: 100px;
  margin: auto;
  perspective: 1000px;
}
#falling-card {
  height: 150px;
  width: 100px;
  background-color: black;
  margin: auto;
  transform: translate3d(0, 40%, 0) rotateX(70deg) rotateY(0deg) rotateZ(80deg);
  animation-name: falling, laydown;
  animation-duration: 2000ms, 1000ms;
  animation-delay: 0ms, 2000ms;
  animation-timing-function: ease-in, ease-out;
  animation-iteration-count: 1, 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="falling-card-parent">
  <div id="falling-card"></div>
</div>
like image 195
Harry Avatar answered Oct 02 '22 21:10

Harry