News

Essential CSS keyframe techniques you need to know

Get up to speed with CSS3’s Keyframe animations, and learn the basics

CSS3SCreen

CSS3SCreen

DOWNLOAD TUTORIAL FILES

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.

×