Thomas Fuchs
Hi, I'm Thomas Fuchs. I'm the author of Zepto.js, of script.aculo.us, and I'm a Ruby on Rails core alumnus. With Amy Hoy I'm building cheerful software, like Noko Time Tracking and Every Time Zone and write books like Retinafy.me.
   Want me to speak at your conference? Contact me!

CSS animation transition-timing-functions and why they are not enough

January 26th, 2011

If you hop over to Apple’s website you’ll notice a fancy shiny new navigation bar. And you’ll notice the fancy shiny animations the navigation bar has. There are even better animations on the Mac subsection, all springy and bouncy and whatnot.

While it’s pleasing to the eye and fun to use, implementing this is less fun:

@-webkit-keyframes open-1 {
    from { opacity:0; -webkit-transform:translate3d( 210px, -145px, 0); }
    25%  { opacity:1; -webkit-transform:translate3d( -15.6px, 4.1px, 0); }
    30%  { opacity:1; -webkit-transform:translate3d( -10.3px, 2.7px, 0); }
    35%  { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
    40%  { opacity:1; -webkit-transform:translate3d( 4.5px, -1.2px, 0); }
    45%  { opacity:1; -webkit-transform:translate3d( 2.9px, -0.8px, 0); }
    50%  { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
    55%  { opacity:1; -webkit-transform:translate3d( -1.3px, 0.3px, 0); }
    60%  { opacity:1; -webkit-transform:translate3d( -0.8px, 0.2px, 0); }
    65%  { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
    70%  { opacity:1; -webkit-transform:translate3d( 0.4px, -0.1px, 0); }
    75%  { opacity:1; -webkit-transform:translate3d( 0.2px, -0.1px, 0); }
    80%  { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
    85%  { opacity:1; -webkit-transform:translate3d( -0.1px, 0, 0); }
    90%  { opacity:1; -webkit-transform:translate3d( -0.1px, 0, 0); }
    to   { opacity:1; -webkit-transform:translate3d( 0, 0, 0); }
}

That’s not exactly easy to change or readable or flexible, or DRY. So why does Apple have to resort to these keyframe-based animations? The reason is that the transition-timing-function CSS property works only with cubic bezier curves, and not with arbitrary easing formulas.

Adding easings would be pretty easy, and in fact you can right now reuse easing calculation like the ones in Scripty2 and just generate CSS keyframes with them. That’s clunky and awkward however, and I think the browser should do that for you.

I’d love to see callbacks to JavaScript in the transition-timing-function to fix this issue, but meanwhile it would be awesome to have a little JavaScript library to help with this. Any takers?