Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 animation-fill-mode polyfill

Preface

Let's pretend that a div is animated from opacity:0; to opacity:1; and i want to keep opacity:1; after the animation ends.

That's what animation-fill-mode:forwards; does.

@keyframes myAnimation {
    from { opacity:0; }
    to { opacity:1; }
}
div {
    opacity:0;
    animation-name:myAnimation;
    animation-delay:1s;
    animation-duration:2s;
    animation-fill-mode:forwards;
}​
<div>just a test</div>​

Run it on jsFiddle

  • Note 1: i didn't include the vendor prefixes here to simplify
  • Note 2: that's just an example, please don't reply with "just use jQuery fadeIn function" etc.

Some things to know

In this answer i read that animation-fill-mode is supported by Chrome 16+, Safari 4+, Firefox 5+.

But animation alone is supported by Chrome 1+ and Opera too. So a general test with Modernizr may return positive even if fill-mode is not supported.

To target animation-fill-mode i added a new test on Modernizr:

Modernizr.addTest('animation-fill-mode',function(){
    return Modernizr.testAllProps('animationFillMode');
});

Now i've a .no-animation-fill-mode class for CSS and Modernizr.animationFillMode for JavaScript.

I also read from CSS3 animations specs that:

an animation specified in the document style sheet will begin at the document load


Finally, the question(s)

Is it ok to run a simple jQuery function at the exact number of seconds the animation ends

$(document).ready(function(){
    if(!Modernizr.animation){
        $('div').delay(1000).fadeIn(2000);
    }else if(!Modernizr.animationFillMode){
        $('div').delay(3000).show();
    }
});

And in CSS:

.no-animation-fill-mode div {
    animation-iteration-count:1;
}
/* or just animation:myAnimation 2s 1s 1; for everyone */

Or is there any known polyfill specific for animation-fill-mode ?


Also, what happens if i use the shorthand syntax

animation:myAnimation 2s 1s forwards;

on browsers supporting animation but not animation-fill-mode ?

Thanks a lot!

like image 323
Giona Avatar asked Sep 21 '12 16:09

Giona


People also ask

What is animation-fill-mode CSS?

The animation-fill-mode property specifies a style for the element when the animation is not playing (before it starts, after it ends, or both). CSS animations do not affect the element before the first keyframe is played or after the last keyframe is played. The animation-fill-mode property can override this behavior.

What is animation-fill-mode backwards?

backwards. When assigned animation-fill-mode: backwards, the target element will take the style values set by the first keyframe of the animation during the animation-delay period. animation-delay sets a time delay until an animation begins, and animation-fill-mode applies during this delay.


1 Answers

If it were me I'd try an opt for the simpler alternative - if possible. I'd downgrade my implementation so that I'm only using what is commonly accepted. Later on, when the feature is more widely supported I then think about implementing it. I rarely consider using a feature that has This is an experimental technology broadcast on documentation pages - but then maybe I should be classed as boring :)

In your example, you could achieve the same result as animation-fill-mode:forwards by defining the end state of your element initially, and using a chained animation (if a delay before the action is needed):

@keyframes waitandhide {
  from { opacity:0; }
  to { opacity:0; }
}
@keyframes show {
  from { opacity:0; }
  to { opacity:1; }
}
div {
  opacity:1;
  animation: waitandhide 2s 0s, show 2s 2s;
}
<div>just a test</div>​

http://jsfiddle.net/RMJ8s/1/

Now it is possible that slower browsers might flash up your initial element states before hiding them away again. But in my experience I've only seen this on very old machines and for pages that have a huge amount of css to render.

Obviously the above does bloat your css a bit more (as you have to duplicate styles), and it would be more complicated when dealing with complex animations. However:

  1. It should work for pretty much any animation situation.
  2. It would avoid the need for JavaScript (save for the $().fadeIn fallback).
  3. It will work on all browsers that support css animation.
  4. You don't run the risk of JS and CSS being/becoming unsynchronised.

With regard to using short-forms it would be best not to if you want to go for as wide reaching browser compatibility as possible. However, as shown in my examples above I have opted for using short-forms because they hold more clarity and I can understand not wanting to write (or read) the long-winded versions all the time. For this reason I would recommend using less to generate your css:

http://lesscss.org/

http://radiatingstar.com/css-keyframes-animations-with-less

like image 108
Pebbl Avatar answered Sep 20 '22 14:09

Pebbl