Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chain CSS animations with infinite loop

Is it possible to chain two animations and then loop this chain indefinitely? {|--ani1--|--ani1--|--ani1--|--ani2--|--ani2--|} x loop

div {
    width: 50px; height: 50px; border: 3px solid black;
    animation: ani1 3s 0s 3, ani2 3s 9s 2;
    /*animation-iteration-count: infinite;*/
}
@keyframes ani1 {
    from { background: green; }
    50% { background: red; }
    to { background: green; }    
}
@keyframes ani2 {
    from { width: 100px; }
    50% { width: 150px; }
    to { width: 100px; }    
}

tested here: http://jsfiddle.net/kQA6D/

like image 994
Qwerty Avatar asked Dec 16 '13 18:12

Qwerty


People also ask

How do you use infinite animation iteration count?

You can use integer values to define a specific amount of times the animation will play. animation-iteration-count: infinite; By using the keyword infinite , the animation will play indefinitely.

Can an element have multiple 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 I add 2 animation in CSS?

You can specify multiple animations--each with their own properties--with a comma.


2 Answers

In short, no (some work arounds are possible)

What your line animation-count: infinte is currently doing is this for the element: animation: ani1 3s 0s infinite, ani2 3s 9s infinite;. So, since the first animation declared has an iteration count of infinite, the second will never be reached

The easiest and most conventional way would be to use javascript and animationEnd to do so (I use Craig Buckler's PrefixedEvent function but it's not necessary)

var elem = document.querySelectorAll("div")[0],
    pfx = ["webkit", "moz", "MS", "o", ""];    
function PrefixedEvent(element, type, callback) {
    for (var p = 0; p < pfx.length; p++) {
        if (!pfx[p]) type = type.toLowerCase();
        element.addEventListener(pfx[p]+type, callback, false);
    }
}    
PrefixedEvent(elem, "animationend", function() { switchAnims(elem) });    
function switchAnims(element) {
    if(element.style.animationName = "ani1") {
        element.style.animationName = "ani2";
    } else {
        element.style.animationName = "ani1";
    }
}

jsFiddle (webkit only - other prefixes need to be added)

Otherwise for a pure CSS fix at the moment you would have to combine them as one animation. For you that would look like

@keyframes aniBoth {
    0%, 16.666%, 33.333%     { background: green; }
    8.333%, 24.999%, 41.666% { background: red; }
    50%                      { background: green; }
    50.001%                  { background:white; width: 100px; }
    75%, 100%                { width: 100px; }
    62.5%, 87.5%             { width: 150px; }
}

jsFiddle (webkit only - other prefixes need to be added)

like image 162
Zach Saucier Avatar answered Oct 31 '22 00:10

Zach Saucier


No, you will need to declare it all in one animation with the specific steps you want, like so:

div {
    width: 50px;
    height: 50px;
    border: 3px solid black;
    animation: ani1 3s 0s infinite;
}
@keyframes ani1 {
    0 { background: green; }
    10% { background: red; }
    20% { background: green; }
    30% { background: red; }
    40% { background: green; }
    50% { background: red; }
    60% { background: green; width: 50px; }
    70% { width: 100px; }
    80% { width: 150px; }
    90% { width: 100px; } 
    100% { width: 150px; }   
}

Demo (Uses -webkit- prefix to be viewable in Chrome)

Alternatively, you could declare your animations separately with a built in gap so that the two animations don't overlap, like so:

div {
    width: 100px;
    height: 50px;
    border: 3px solid black;
    animation: ani1 12s 0s infinite, ani2 12s 0s infinite;
}
@keyframes ani1 {
    0%, 60%, 100% { background: white; }
    20%, 40% { background: green; }
    10%, 30%, 50% { background: red; }
}

@keyframes ani2 {
    60%, 80%, 100% { width: 100px; }
    70%, 90% { width: 150px; } 
}

Demo (Uses -webkit- prefix to be viewable in Chrome)

like image 20
shshaw Avatar answered Oct 31 '22 01:10

shshaw