CSS3 Transitions Chaining

Chaining Multiple CSS Animations

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>

CSS3 transitions chaining

I believe you want a CSS3 animation where you define the CSS styles at different points in the animation and the browser does the tweening for you. Here's one description of it: http://css3.bradshawenterprises.com/animations/.

You will have to check on browser support for your targeted browsers.

Here's a demo that works in Chrome. The animation is pure CSS3, I only use Javascript to initiate and reset the animation:

http://jsfiddle.net/jfriend00/fhemr/

The CSS could be modified to make it work in Firefox 5+ also.

#box {
height: 100px;
width: 100px;
background-color: #777;
position: absolute;
left: 5px;
top: 5px;
opacity: 0;
}

@-webkit-keyframes demo {
0% {
left: 10px;
}
22% {
opacity: 1;
}
77% {
left: 30px;
}
100% {
left: 50px;
opacity: 0;
}
}

.demo {
-webkit-animation-name: demo;
-webkit-animation-duration: 900ms;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
}

Chain/sequence animation in CSS

As others have suggested, use animation-delay to offset each element's animation.

In order to loop the entire group, multiply the animation duration by the number of elements and change your keyframes accordingly. Below, I've multiplied the animation duration by three and divided the keyframe percentages by three.

If you have a large number of elements or they are added dynamically, you may want to consider using JavaScript, as mentioned here.

a {  padding: 6px;  display: block;  width: 50px;  font-size: 17px;  margin: 10px auto;  border: 2px solid;  text-decoration: none;  box-shadow: 0 0 0 rgba(204, 169, 44, 0.4);  animation: pulse 6s infinite;}
.btn-100 { animation-delay: 0s;}.btn-500 { animation-delay: 2s;}.btn-1250 { animation-delay: 4s;}
@keyframes pulse { 0% { -moz-box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4); box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4); } 23.333% { -moz-box-shadow: 0 0 0 10px rgba(255, 208, 0, 0.2); box-shadow: 00 0 0 10px rgba(255, 208, 0, 0.2); } 33.333% { -moz-box-shadow: 0 0 0 0 rgba(204, 169, 44, 0); box-shadow: 0 0 0 0 rgba(204, 169, 44, 0); }}
<a class="btn-100" href="#">100</a><a class="btn-500" href="#">500</a><a class="btn-1250" href="#">1250</a>

css chain transition animation

The trick is to perform an animation first to hide all of the elements (when the page loads), and chain that to the animation that will reveal the elements. This is a working example for you in PURE CSS & HTML:

div.slideIn {           position: absolute;           top: 200px;           width: 100px;           height: 100px;           border: 1px solid black;           animation-name: hide, slideIn;          animation-duration: 5s;          animation-timing-function: ease-in;          animation-iteration-count: 1;           -moz-animation-name: hide, slideIn;          -moz-animation-duration: 5s;          -moz-animation-timing-function: ease-in;          -moz-animation-iteration-count: 1;           -webkit-animation-name: hide, slideIn;          -webkit-animation-duration: 5s;          -webkit-animation-timing-function: ease-in;          -webkit-animation-iteration-count: 1;           -o-animation-name: hide, slideIn;          -o-animation-duration: 5s;          -o-animation-timing-function: ease-in;          -o-animation-iteration-count: 1;           opacity: 1;      }       div.slideIn.first {          left: 50px;           animation-delay: 0s, 0s;          -moz-animation-delay: 0s, 0s;          -webkit-animation-delay: 0s, 0s;          -o-animation-delay: 0s, 0s;      }      div.slideIn.second {          left: 150px;          animation-delay: 0s, 2s;          -moz-animation-delay: 0s, 2s;          -webkit-animation-delay: 0s, 2s;          -o-animation-delay: 0s, 2s;      }      div.slideIn.third {          left: 250px;          animation-delay: 0s, 4s;          -moz-animation-delay: 0s, 4s;          -webkit-animation-delay: 0s, 4s;          -o-animation-delay: 0s, 4s;      }      @keyframes hide      {           from { opacity: 0; } to { opacity: 0 }      }      @-moz-keyframes hide      {           from { opacity: 0; } to { opacity: 0 }      }      @-webkit-keyframes hide      {           from { opacity: 0; } to { opacity: 0 }      }      @-o-keyframes hide      {           from { opacity: 0; } to { opacity: 0 }      }      @keyframes slideIn      {             0% { opacity: 0; top: -100px; }            1% { opacity: 1; top: -100px; }          100% { opacity: 1; top:  200px; }       }       @-moz-keyframes slideIn      {             0% { opacity: 0; top: -100px; }            1% { opacity: 1; top: -100px; }          100% { opacity: 1; top:  200px; }       }       @-webkit-keyframes slideIn      {             0% { opacity: 0; top: -100px; }            1% { opacity: 1; top: -100px; }          100% { opacity: 1; top:  200px; }       }       @-o-keyframes slideIn      {             0% { opacity: 0; top: -100px; }            1% { opacity: 1; top: -100px; }          100% { opacity: 1; top:  200px; }       } ]    
<div class="slideIn first">I slid in</div>     <div class="slideIn second">I'm 2nd</div>     <div class="slideIn third">I'm 3rd</div> 

CSS3 Chain Animations

There are several ways to chain the animations - there's the pure CSS way, using -webkit-animation-delay, where you define multiple animations and tell the browser when to start them, e.g.

-webkit-animation: First 1s, Second 2s;
-webkit-animation-delay: 0s, 1s;
/* or -moz etc.. instead of -webkit */

Another way is to bind to the animation end event, then start another. I've found this to be unreliable, though.

$('#id')
.bind('webkitAnimationEnd',function(){ Animate2() })
.css('-webkit-animation','First 1s');

The third way is to set timeouts in Javascript and change the css animation property. This is what I use most of the time, as it is the most flexible: you can easily change the timing, cancel animation sequences, add new and different ones, and I've never had a fail issue like I have binding to the transitionEnd event.

$('#id').css('-webkit-animation','First 1s');
window.setTimeout('Animate2("id")', 1000);
function Animate2....

It's more code than a bind, and more than CSS, of course, but it's relable and more flexible, imho.



Related Topics



Leave a reply



Submit