
When we create simple animations of elements between two states, CSS transitions are easy to implement and use, but this simplicity comes with a few significant limitations.
We can create keyframe animations with greater control using CSS3 keyframe animations, where authors can create smooth, maintainable animations that perform well and don’t require reams of scripting. The @keyframe rule is now supported across all modern browsers using the prefixes -webkit-, -moz- or -o- respectively.
It lets authors control the intermediate steps in a CSS animation sequence by establishing keyframes along the animation sequence by specifying the changes by either percentages or the keywords “from” and “to”. This gives you a lot more control over the steps of the animation sequence than if youwere using just transitions. So in this tutorial, we’ll take a look at the basics of animating an element across your page and then create examples along the way to allow you to understand how keyframes are used.
The HTML
First thing we’re going to do is create a ball to play with. We’re going to use this for the first couple of demos and then look to create something a bit more useful later in the tutorial. So open up your favorite text editor and add in this block of HTML within the <body> element.
001 <section class=”container”> 002 <h2>Moving Ball!</h2> 003 <div class=”ball”></div> 004 </section>
Keyframe syntax
Open up our CSS file now and take a good look at our keyframe syntax. A keyframe animation always starts with a unique name chosen by you – the author. So here we’ll give it a name of ‘moving’ and then the animation sequence itself may be specified in two ways. The first of these is a ‘from’ and ‘to’ declaration.
001 @-webkit-keyframes moving {
002 from { }
003 to { }
004 }
From and to
Within our ‘from’ and ‘to’ declaration, we can add in a ‘transform: translate’ property and value. So here we want to move our ball across our page on the x axis starting from 0px, and finishing up 500px to the right. We can think of this as a function and we now need to create our ball and call this function. So let’s do that in the next few steps.
001 @-webkit-keyframes moving {
002 from { -webkit-transform:translateX(0px);}
003 to { -webkit-transform:translateX(500px);}
004 }
Create the ball
What we need to do now is to create our ball – which is just some simple CSS that creates a circle. We will give the ball a nice purple colour and make it 100px in diameter and then round it off into a circle by setting its border radius to 100 per cent. Then we’ll give it some margin on top to push it down slightly.
001 .ball {
002 background:#CC66FF;
003 width: 100px;
004 height: 100px;
005 border-radius: 100%;
006 margin: 20px 0;
007 }
Move the ball
Now within our ‘ball’ CSS rule, go ahead and add this next piece of code. What this does is calls our keyframe function which we called ‘moving’, and move it across our page at a duration of two seconds. We can make the animation a little smoother by adding in an ‘ease-out’ function.
001 -webkit-animation-name: moving; 002 -webkit-animation-duration: 2s; 003 -webkit-animation-timing-function:ease-out;
Use percentages
The second way of specifying our animation sequence is by using percentages. Percentages give us a lot more control and allow us to create more complex animations when needed. What we’re doing here is simply making the ball move across the page on the x axis and back again.
001 @-webkit-keyframes moving {
002 0% { -webkit-transform: translateX(0px);}
003 50% { -webkit-transform:translateX(500px);}
004 100% { -webkit-transform: translateX(0px);}
005 }
More complex animation
Now let’s make a slightly more complex animation by combining percentages with the ‘transform: translate’ property. So here we will make the ball drop 200px and then move up diagonally and then slide back to where it started. Simply changing the percentages will either speed up that animation, or slow it down. So setting the percentages more evenly, we result in a much smoother animation.
001 @-webkit-keyframes slide {
002 0% { -webkit-transform:translateX(0px);}
003 30% { -webkit-transform:translateY(200px);}
004 70% { -webkit-transform:translateX(100px);}
005 100% { -webkit-transform:translateX(0px);}
006 }
Slide animation
Now that we have set the keyframe function, let’s add the CSS to our ‘ball’ rule to make the animation happen. We need to specify the keyframe animation name, which is ‘slide’ and then set the duration, easing function and for added control, a one second delay.
001 -webkit-animation-name: slide; 002 -webkit-animation-duration: 4s; 003 -webkit-animation-timing-function:ease-in-out; 004 -webkit-animation-delay: 1000ms;
Up and down
Carrying on using percentages, let’s take a look at how we can simply move the ball up and down on the y axis. Again we’ll make sure we specify a halfway mark for smoother animations and we’ll keep the same animation name as we used before which is “moving”.
001 @-webkit-keyframes moving {
002 0% { -webkit-transform:translateY(0px);}
003 50% { -webkit-transform:translateY(200px);}
004 100% { -webkit-transform:translateY(0px);}
005 }
Infinite animation
With our keyframes now set, let’s jump back into our ‘ball’ rule, remove any animation CSS we have, and replace it with this. The main property we’ll be looking at here is the ‘iteration-count:’ property, with the value of ‘infinite’. As the name implies, this will allow us to create
an infinite animation.
001 -webkit-animation-name: moving; 002 -webkit-animation-duration: 3s; 003 -webkit-animation-timing-function: ease-in-out; 004 -webkit-animation-delay: 1000ms; 005 -webkit-animation-iteration-count:infinite; 006
Shorthand
One of the cool things about CSS, is how easy we can write CSS shorthand and the animation property is no exception. What we can do is combine all those CSS properties and values we wrote in the last step and put them all into one line. The order doesn’t matter except when using both duration and delay, they need to be in that order (3 second duration and 1 second delay)
001 -webkit-animation: moving 3s 1s ease infinite;
Arc the animation
Still using the ‘moving’ keyframe animation, what we can do is look at how we can arc our animation by using the ‘cubic-bezier()’ property. Firstly we need to add some additional HTML and then write a new keyframe animation called ‘ball-x’. Combining this with the ‘moving’ animation, we can create something that looks like a ball that drops in and bounces. With a little more thinking, we can make this look really good.
001 <div class=”ball-arc”>–––
002 <div class=”ball”></div>
003 </div>
004 .ball-arc {
005 -webkit-animation: ball-x 2.5s cubic-bezier(0, 0, 0.35, 1);
006 }
007 @-webkit-keyframes ball-x {
008 0% { -webkit-transform: translateX(-275px); }
009 100% { -webkit-transform:translateX(0px); }
010 }
Ball and shadow
In this next few steps, we’re going to add some additional CSS to our ball and make the ball look like it’s bouncing up and down on a piece of string with an animated shadow underneath for added realism. First, we need to open up our HTML file and add some additional HTML mark-up.
001 <div class=”container”> 002 <div class=”line”></div> 003 <div class=”ball”></div> 004 <div class=”shadow”></div> 005 </div><!-- END container --> 006
Container
Adding a container that wraps around our ball is important to allow us full control of how we style this. Positioning the container ‘relative’ will allow us to ‘absolute’ position our line that our ball will move up and down on. We’re going to allow enough room going down with 400px height and then squeeze it all in with only 150px in width.
001 .container {
002 position: relative;
003 width: 150px;
004 height: 400px;
005 }
006
Create the keyframes
We’re now going to add two keyframe sequences, one for our moving ball and the other for our animated shadow. The idea here is to animate the shadows opacity and width. So when the ball drops down, the shadow will darken and expand out. Then when the ball lifts up, the shadow will lighten and animate back in again.
001 @-webkit-keyframes moving {
002 50% { top: 90px;}
003 100% { top: 0px;}
004 }
005 @-webkit-keyframes shadow {
006 50% { margin:0px 20% 0px 20%;
opacity: 0.8; }
007 100% { margin: 0px; opacity: 0.1;}
008 }
009
Add the line
Using absolute positioning, we easily add a black line that will go through the ball and look like it’s attached to it. It’s up to you how long you want the line to be, but we’ve made it 100px in height. With a little bit of tweaking, we can position it so the bottom end never shows once the animation starts.
001 .line {
002 background: url(‘../imgs/line.png’);
003 position: absolute;
004 width: 25px;
005 height: 100px;
006 top: -10px;
007 left: 62px;
008 }
Change shadow opacity
As mentioned earlier on, our shadow’s width
needs to be able to animate in and out in time with the ball. To achieve this we will need to make sure that its width is not specified like you normally would as this would then make the whole shadow move from side-to-side, which is not what we want. Then we are going to make sure the shadow’s opacity is set very low so that we can animate its opacity as well.
001 .shadow {
003 position: relative;
004 height: 16px;
005 background: #999;
006 opacity: 0.1;
007 border-radius: 100%;
008 margin: 0px 0px 0px 0px;
009 top: 100px;
010 -webkit-animation: shadow ease 2s infinite;
011 }
012
Animate the ball
We’ve kept the same styles for our ball as before and to keep things nice and clean, we will be using shorthand for our animation property. With the ‘infinite’ value added, the ball will then bobble up and down forever! Lastly to give this a little more realism, we can add a ‘scaleY()’ value within our moving keyframe to give us the illusion that the ball is stretching when it moves down (it’s not of course). Perhaps think of this ball as a balloon full of water.
001 .ball {
002 position: relative;
003 top: 0px;
004 background:#CC66FF;
005 width: 150px;
006 height: 150px;
007 border-radius: 100%;
008 -webkit-animation: moving ease 2s infinite;
009 }
010 50% { top: 90px; -webkit-transform:scaleY(1.1);}
011
Bouncing ball
In this final project, we’ll create a simple bouncing ball using a selection of percentages for our keyframe sequence. But first we need to write some HTML mark-up. We’re going to use CSS to bring in our images and the ball rule will come first. We will make the ball fairly big at 200px and then give it some breathing space on top with a 20px margin.
001 .ball {
002 background: url(‘../imgs/football.png’);
003 width: 200px;
004 height: 200px;
005 margin: 20px 0px;
006 }
Add some colour
Next up will be our strip of grass. This will give our simple project some colour and you can always experiment with different types of grass. Then we need to position absolute as we need to shift it into place. As we have set the positioning to absolute, we can also target the z-index so the ball doesn’t bounce in behind it.
001 .grass {
002 background:url(‘../imgs/grass.jpg’) no-repeat;
003 height: 50px;
004 width: 400px;
005 position: absolute;
006 top: 280px;
007 left:-85px;
008 z-index: -1;
009 }
The bounce keyframes
Using percentages and the ‘translateY’ property allows us to really get control of how our ball will bounce. This will give us five bounces before the ball comes to rest. We’ve also put a timing function on the bounces, which will give us a more realistic look. Then in the next step we’ll add an ease-in timing function to make it look even more realistic.
001 @-webkit-keyframes ball-y {
002 0% { -webkit-transform: translateY(-255px); }
003 40% { -webkit-transform:translateY(-200px); }
004 65% { -webkit-transform: translateY(-85px); }
005 82% { -webkit-transform: translateY(-50px); }
006 92% { -webkit-transform:translateY(-20px); }
007 25%, 55%, 75%, 87%, 97%, 100% {-webkit-transform: translateY(0px);
008 -webkit-animation-timing-function:ease-out;}
009 }
010
Start the animation
All there is left to do now, is add in our animation declaration within our ‘.ball’ class. And that’s it. There is a lot more we can do with this, and we encourage you to experiment with what you’ve learned. One thing you could try is to create a animated shadow for this using the same techniques as before.
