skip to content

CSS: Bouncing Ball Animation

Following on from our introduction to CSS Transforms, and using lessons learned from implementing 3D Transforms and Animations, this article presents an animation of a bouncing ball - for now just in two dimensions, but it shouldn't be too much of a step to move to three.

These animation will now work in Safari, Chrome, Firefox, Opera and Internet Explore 10. Not all browsers support 3D transformations so the effect can be less dramatic. At the time of writing only WebKit browsers still require a prefix.

Defining the animation keyframes

For this animation we're going to use two keyframes - one to translate the ball horizontally with a constant velocity and a second to apply a roughly parabolic vertical bouncing motion. It is possible to combined both horizontal and vertical translations into a single keyframe, but that won't work for the effect we're after.

The horizontal motion can be easily implemented using the following keyframe:

<style> @-webkit-keyframes travel { from { } to { left: 640px; } } @keyframes travel { from { } to { left: 640px; } } </style>

This keyframe will be referenced later using the assigned name 'travel' and applied using a linear transition timing function that changes direction with each iteration.

For the vertical, bouncing, animation, we're going to make use of the ease-in and ease-out timing functions to simulate the effects of a gravity field:

<style> @-webkit-keyframes bounce { from, to { bottom: 0; -webkit-animation-timing-function: ease-out; } 50% { bottom: 220px; -webkit-animation-timing-function: ease-in; } } @keyframes bounce { from, to { botttom: 0; animation-timing-function: ease-out; } 50% { bottom: 220px; animation-timing-function: ease-in; } } </style>

This keyframe has been named 'bounce' for future reference.

Combining the two keyframes will move our 'ball' horizontally across 640 pixels and vertically through 220 pixels. These values of course need to be adjusted to fit the size of the 'stage'.

Setting the stage for animation

As always, we start by setting up a 'stage' in which the animation is to be performed. In this case a simple DIV with dimensions of 660 x 240 pixels. It would be nice to just let the width be 100%, but it's difficult to place some elements without knowing the exact pixel width.

<style> #stage { position: relative; margin: 1em auto; width: 660px; height: 240px; border: 2px solid #666; background: #cff; } </style>

Within this stage we're going to set up a DIV element that moves back and forth horizontally, and within that a DIV representing the 'ball' that bounces up and down:

<style> #traveler { position: absolute; width: 20px; height: 240px; -webkit-animation-name: travel; -webkit-animation-timing-function: linear; -webkit-animation-iteration-count: infinite; -webkit-animation-direction: alternate; -webkit-animation-duration: 4.8s; animation-name: travel; animation-timing-function: linear; animation-iteration-count: infinite; animation-direction: alternate; animation-duration: 4.8s; } #bouncer { position: absolute; width: 20px; height: 20px; background: red; border-radius: 10px; -webkit-animation-name: bounce; -webkit-animation-iteration-count: infinite; -webkit-animation-duration: 4.2s; animation-name: bounce; animation-iteration-count: infinite; animation-duration: 4.2s; } </style>

So the dimensions of our 'ball' will be 20 x 20 pixels, with rounded corners.

Setting the ball in motion

We finish with some simple HTML markup:

<div id="stage"> <div id="traveler"> <div id="bouncer"><!-- be the ball --></div> </div> </div>

If your browser supports it the animation will start automatically and continues indefinitely in the box (or #stage) below:


We've added one extra element and some styles to highlight the x- and y-components of the animation, but otherwise the code is exactly as presented. No JavaScript is required.

Here's a screencast (QuickTime 777kb) showing the effect. In Safari the animation is actually quite smooth. On the iPhone there is some jerkiness, but not as bad as this screencast.

Tumbling leaf demonstration

With only a few changes to the bouncing ball animation, we can generate much more complex effects, such as this tumbling leaf:

To explain how this works using rotations in three dimensions is difficult, but you can download the CSS and try it out for yourself:

You can view the effect here as a screencast (QuickTime 3.0Mb). Again, the screencast doesn't really do justice to the animation which is much smoother - at least in Safari.


User Comments

Post your comment or question

10 November, 2016

Thank you so much for your awesome and well explained examples, I particularly love the autumn leaf, and even added a rotateY to it . As to the hover on one object to animate the other (or both): I tried to hover on one to animate two others: .box1:hover + .box2 + .box3 but it seems this doesn't work? Just wondering, the possible effects are awesome anyway ...

3 January, 2012

Inspired I created this variation on the theme for Drupal sites:

28 August, 2011

Hey, this looks like some great work, however it is not presented in a way that is easy to understand. Can you provide a secondary page that merely has each example in it?
I.E. two separate HTML pages that each have one of the stages?

This should be a trivial refactor for you, however because of the way it is presented, there are six or seven different style tags that are applied...

20 August, 2011

Doesnt work in IE and MAC firefox can you suggest anything to work this.

It does work in Firefox 6.0 (Mac), just without the 3D-effects on the last example, and may work in Internet Explorer 10.0 (using a -ms- prefix for the transition styles).

2 June, 2011

Depois desses códigos a web está mais amigavel!
very nice brother!

31 May, 2011

This is very nice. I am going to use it some where on my projects.