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.
- CSS: bounce-animation.css
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:
- CSS: leaf-animation.css
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.
Related Articles - Transforms and Transitions
- CSS Transition Timing Functions
- CSS Animation Using CSS Transforms
- CSS Upgraded fading slideshow
- CSS Bouncing Ball Animation
- CSS Infinite Animated Photo Wheel
- CSS Animated Background Gradients
- CSS An actual 3D bar chart
- CSS Photo Rotator with 3D Effects
- CSS 3D Transforms and Animations
- JavaScript CSS Animated Fireworks
- JavaScript Animating objects over a curved path
- CSS Fading slideshow with a touch of JavaScript
- JavaScript Controlling CSS Animations
Gwunderi 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 ...
RdeBoer 3 January, 2012
Brilliant!
Inspired I created this variation on the theme for Drupal sites: www.flink.com.au/tips-tricks/done-60-seconds-getting-funky-css3
Cory 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...
pad 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).
Melhor Free 2 June, 2011
Depois desses códigos a web está mais amigavel!
very nice brother!
Said Suleiman Juma 31 May, 2011
This is very nice. I am going to use it some where on my projects.