Life at the bleeding edge (of web standards)

Main menu

Post navigation

CSS Animations with only one keyframe

This is a very quick tip, about a pet peeve of mine in almost every CSS animation I see. As you may know, I’m a sucker for reducing the amount of code (as long as it remains human readable of course). I demonstrated a very similar example in my “CSS in the 4th dimension” talk, but I recently realized I never blogged about it (or seen anyone else do so).

What many don’t know, is that you don’t need these two keyframes at all, since they basically replicate the same state as the one in the .heart rule. To quote the CSS Animations spec:

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.

Therefore, the code could actually be as simple as:

@keyframes pound {
50% { transform: scale(1.4); }
}

This trick is very useful for providing fallbacks that are the same as the first or last keyframe, without having to repeat them in the @keyframes rule. Of course it doesn’t only apply to animations where you only have one keyframe beyond from and/or to. You can omit the from and to keyframes in every animation, when you want them to be the same as the styles that are applied to the element anyway.

Of course, to make this particular animation appear more natural, it would be much more wise to do something like this, still with only one keyframe (the from state is dynamically generated by the browser):

which just reverses every even iteration, instead of trying to have both states (shrinking and growing) in the animation. The reason this looks more natural is that animation-direction: alternate; (which is what the alternate keyword does in the animation shorthand) also reverses the timing (easing) function for the reversed iterations.

Post navigation

That post would have made an awesome CSS Valentine’s Day blog post (nice one Lea)

http://lea.verou.me/ Lea Verou

Haha, you’re right! Although the concept applies to many more kinds of CSS animation.

http://www.facebook.com/mar1ly Marily Nika

yes but the heart sure got my attention much faster!

http://lea.verou.me/ Lea Verou

And that wasn’t even intentional, LOL!

http://rachelnabors.com Rachel Nabors

Lovely test case! I see a lot of animations that have an unnecessary number of keyframes these days–I’ve made a few myself! But fewer keyframes means less work for you and less to maintain. Relax, let the computer do the math!

http://twitter.com/kevinwhinnery Kevin Whinnery

Nice tip! Wasn’t aware of the default behaviors.

http://twitter.com/donvodki ♠ DONVODKI

pretty awesome. thanks Lea!

http://twitter.com/AllThingsSmitty Matt Smith

Fantastic

http://www.facebook.com/cezar.espinola Cezar Sá Espinola

For the last example you say that you’re going to use animation-direction: reverse, but the example actually uses animation-direction: alternate which reverses the animation only after it plays as normal first.

It would be even more useful if the from/to value actually would be dynamic. For example if you would add

.heart:hover { transform: scale(.5); }

it should animate from .5 to 1.4, but instead it keeps animating from 1 to 1.4. Not sure if this is a technical limitation so it doesn’t have to check the values all the time and performance is better.

http://qwertjsblog.altervista.org/ Qwertj

Nice tip!
I see the last example with some flickering, while the others run smoothly
I think that’s why when it reverses animation he repaint the heart from the start, without rescale it back.

Nora Brown

Wow — dabblet is amazing. I don’t have to leave your post to fiddle with the examples and create a slow pulsing blue heart instead. Totally delightful!

Thank you for posting this, but i have a question. How is it possible that the animation is working on this website but not working when i copy-paste the code?

http://lea.verou.me/ Lea Verou

You’re missing the necessary prefixes (or just use prefixfree, that’s what’s used in the above examples)

Daniel Smith

love your blog, lots of great info on here!

http://www.y8u.org/ Y8 Games

This is an outstanding informational article. I even have very enjoyed reading your views and thoughts on this subject. you’ve got got given Pine Tree State things to ponder.

ninjamoves

does @keyframes on css3 adopted the physics from cornaSDk

RT

Was browsing along and noticed I’ve been getting tips from hot female web designers.

Why can’t I work with hot female web designers!?

Peter L

This was a nice idea but unfortunately I discovered that not all user-agents construct styles for the omitted keyframes, for example IE10. For animations to work properly in all browsers, you must still specify ALL the keyframes and ALL the properties you wish to animate. For more details see this article: http://www.sitepoint.com/animation-keyframe-gotcha/

http://lea.verou.me/ Lea Verou

Your recommendation is like using a sledgehammer to push a button. The issue 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.

Peter L

I don’t understand what you mean by ignore, but it certainly *solves* the issue. There is no downside to specifying all the keyframes, other than adding a few more bytes to your stylesheet. If someone gets into the habit of not specifying all the keyframes (like I did) without knowing the potential problems with some properties such as box-shadow, text-shadow, (I’m guessing there’s more). They’ll be wondering why their animation is not working properly. And the answer is because they omitted some keyframes and didn’t specify values for the properties they wish to animate. It should be taken into account at least.

For those obsessed with saving a few bytes on their stylesheet, you can omit keyframes for -webkit-, -moz-, and -o- prefixes but for IE10 + IE11 you must write all the keyframes 0% – 100% and in each of those keyframes – state the properties you wish to animate and state the values you want. (e.g. just 100% { text-shadow: 10px 10px #ddd; } will not animate. But also including 0% { text-shadow 0 0 #ddd; } will make it animate).

And you’ll never know how future browsers might behave, so it’s safest just to simply write all the keyframes anyway. It’s standard practice and there’s nothing wrong with it, so why cause yourself some potential headaches by omitting keyframes?

If God wills before she leaves this world she will see what she has done to her once beautiful body and she will regret it

Sandeep

hi … this is a useful trick.. thank you for that .
I have a question:
can we delay animation ? if yes , How ?

Sandeep

I mean stop for a while and start again..

Jared

Love this. Thank you.

http://www.woopi.com.ar Sebastián

Hey Lea! I was searching some information about CSS3 scaling objects with scale(). The issue I’ve founded is that when you transform anything with scale(), it gets pixelated in any webkit-based browser. It renders perfect in Firefox, for example. Even with this example you wrote in this post, you can see the heart pixelating when animations occurs. What can we do about it? Is there any method to avoid this problem on a webkit browser? Thanks!!!