The Animation Keyframe Gotcha

Contributing Editor

I’m a big fan of CSS3 animations. Despite a tentative start and some concerns about whether they trespass on JavaScript’s behavioral responsibilities, CSS3 animations are widely supported, easy to use and permit slick effects that would have been impossible without Flash a few years ago.

Unfortunately, not all is rosy in the CSS3 garden and browser vendors often spray manure over your patch. Consider the following glowing element animation:

div
{
	width: 8em;
	font-weight: bold;
	text-align: center;
	padding: 0.5em 0;
	margin: 50px auto;
	color: #fff;
	background-color: #00c;
	border-radius: 3px;
	animation: glow 3s ease-in-out infinite;
}

@keyframes glow {
	50%  { box-shadow: 0 0 20px #aaf; }
}

View the demonstration page…
animation

(Note: -webkit prefixes for the animation and keyframes properties are currently required for Chrome, Safari and Opera 15+ but not shown in the code above. They have been added to the demonstration page.)

The animation works well in recent editions of Firefox, Chrome, Safari and Opera — but not IE10 or IE11.

Before you launch into a “it’s IE6 all over again” diatribe, let’s take a closer look at the W3C CSS3 Animations Working Draft document. In section 4. Keyframes you’ll find the following statement:

ISSUE 1 Need to describe what happens if a property is not present in all keyframes.

We have only defined one keyframe at 50% but have not explicitly defined properties at 0% and 100%. I suspect the Webkit/Blink and Gecko browsers are defaulting to box-shadow: 0px 0px 0px rgba(0,0,0,0);. However, IE’s Trident engine appears to default to box-shadow: none; — and it’s impossible to animate from “nothing” to “something”.

Strictly speaking, no browser is making a correct assumption because the specification is incomplete. Perhaps the Webkit/Blink and Gecko teams have made a more useful choice but that doesn’t make it correct. Yet.

That said, you would have hoped IE would start the animation if box-shadow: 0px 0px 0px rgba(0,0,0,0); were defined in the div selector. The specification states:

If a ’0%’ or ‘from’ keyframe is not specified, then the user agent constructs a ’0%’ keyframe using the computed values of the properties being animated. If a ’100%’ or ‘to’ keyframe is not specified, then the user agent constructs a ’100%’ keyframe using the computed values of the properties being animated.

To be fair, the CSS3 animation specification is evolving so it’s not surprising to find implementation differences. Fortunately, you can avoid cross-browser animation inconsistencies by following a few simple rules:

  1. Always include keyframes at 0% / from and 100% / to. Never forget the ‘%’ symbol either — unlike other properties, 0 and 0% are not equivalent.
  2. Always define every property being animated within every keyframe — 0% and 100% are especially important.
  3. Test often using a variety of browsers!

To ensure the glow animation works everywhere, we must change the keyframes definition:

@keyframes glow
{
	0%   { box-shadow: 0 0 0px rgba(0,0,0,0); }
	50%  { box-shadow: 0 0 20px #aaf; }
	100% { box-shadow: 0 0 0px rgba(0,0,0,0); }
}

There are no guarantees, but this code should continue work regardless of any updates to the applications or the CSS3 Animation specification.

Has this issue caught you out? Did you find a fix? Or did you give up and blame the browser?!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • George Langley

    Is it just me, or does this look like crap in Mac Safari 5.1.10? I’m seeing a square box extrude into the distance from the left side with a slight glow along the top of the div, then suddenly bursts into the full proper glow and fades out as expected. And I get NOTHING in Mac Firefox 12.0! It just sits there, even with all three key frames added. Works fine in Chrome 29 and Opera 12.
    Doesn’t get me too excited to use things that don’t work.

    • Anonymous

      Those browsers are a little old. Safari 7 and Firefox 24 are the current versions – it should work well in those.

  • George Langley

    Admittedly, yes. But we always need to think how far back are we willing to go (based on user stats, of course) and those are my minimums (Mac Snow Leopard, Windows XP, WIndows 7).

  • Anonymous

    I think you’d be unlucky to find a large number of people using Firefox 12 on your site. The browser has auto-updated since v5 (if I recall correctly). I would suspect most Mac users have migrated to Safari 6 at least too.

    Besides that, is it a problem? If animations aren’t supported they simply aren’t shown. That’s unlikely to break your application.

  • Anonymous

    This only applies to cases like the one you mentioned, where you’re using the initial value for those keyframes and a certain browser’s initial value is not animatable. For example, this works fine in IE10: http://dabblet.com/gist/6894938
    You can’t ignore this issue by just specifying all keyframes, it will come back to bite you in other cases, e.g. transitions.

    • Anonymous

      Thanks Lea. Absolutely: the key issue is you can’t depend on the browser’s initial values — which is fair enough. In addition, it seems IE10 doesn’t necessarily assume an animated property’s initial value is the same as the one defined in the basic (non-animated) selector.

  • Anonymous

    In any case, this should be reported as a bug asap.

    Did you reproduce it with other properties as well or just box-shadow?

    • Anonymous

      Good point. I’m sure I tried a few, but can’t recall which. I’ll do some further investigation…