Chris Bateman

Bouncing Along: CSS3 Animation

CSS3 allows for several easing effects when you animate or transition an element: linear, ease, ease-in, ease-out, and ease-in-out. You can also specify custom easing with cubic-bezier (and here’s a great tool for doing that).

Unfortunately, there’s no way to specify more complicated motions, such as the bounce easing in jQuery UI (see easeOutBounce). To recreate that effect in CSS3, we’ll have to create custom animation keyframes. I used a graph of the jQuery effect to estimate my keyframes:

  • (time – position)
  • 0 – 0
  • 37 – 100
  • 55 – 75
  • 73 – 100
  • 82 – 93
  • 91 – 100
  • 96 – 98
  • 100 – 100

Which, translated to pixels, gives us the following CSS:

@keyframes bounce {
    0%   { top:000px; }
    37%  { top:500px; }
    55%  { top:375px; }
    73%  { top:500px; }
    82%  { top:465px; }
    91%  { top:500px; }
    96%  { top:490px; }
    100% { top:500px; }
}

So here’s our first demo. The gist of it is there, but it feels pretty choppy; it just doesn’t have the right gravity.  The default easing is ‘ease’, and it gets applied to every keyframe – we need to add specific easing for each keyframe in our animation:

@keyframes bounce {
    0%   { top:000px; animation-timing-function:ease-in;  }
    37%  { top:500px; animation-timing-function:ease-out; }
    55%  { top:375px; animation-timing-function:ease-in;  }
    73%  { top:500px; animation-timing-function:ease-out; }
    82%  { top:465px; animation-timing-function:ease-in;  }
    91%  { top:500px; animation-timing-function:ease-out; }
    96%  { top:490px; animation-timing-function:ease-in;  }
    100% { top:500px; }
}

The second demo looks much nicer; you can feel the weight of the box hitting the floor.

The only problem is that you have to manually calculate the pixel values for every keyframe of every element you want to animate. You could save the trouble by creating a JavaScript class to do it for you (I may or may not post an example of that).

Of course, you’ll need a modern browser to see the demos in action.

Tell me what you think: @batemanchris