Qwerty
Qwerty

Reputation: 31949

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/

Upvotes: 7

Views: 14007

Answers (2)

shshaw
shshaw

Reputation: 3213

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)

Upvotes: 4

Zach Saucier
Zach Saucier

Reputation: 25954

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)

Upvotes: 5

Related Questions