Animation With CSS: It’s Easier Than You Think

When we combine movements (transforms) of inanimate objects over different timeframes (transitions) we get animation. CSS3 expands on what’s possible with transforms and transitions with the aptly named animations module and I’d like to spend some time today looking through that module.

I’ve created a simple animation demo to go along with this post. By no means is this award winning animation. In fact it’s pretty cheesy, but hopefully it illustrates how to work with animation.

Browser support for animation is limited to Webkit browsers like Safari and Chrome as well as Firefox. Animation is coming to IE10 and as of now there’s unknown support in Opera. For now you also need to use vendor prefixes, though I won’t be showing the prefixes in this post.

Keyframe sketches of a parrot for an animation


The first thing we need to understand with animation is the idea of keyframes. If you’ve ever worked with Flash or similar you should know what keyframes are.

With transitions we had a starting point and ending point. What we didn’t have was anything in between. Keyframes give us the in between. They give us finer control over the intermediate stages between beginning and ending.

Essentially they define a series of start and end points, with all intermediate keyframes being the ending point for one transition and the starting point for the next. This allows for the variance of durations and timing functions through the entire animation sequence.

@keyframes Rule

In css3 keyframes are specified using an @rule, followed by a user defined name for the animation. Inside are lists of property: value pairs set at different % over the animation. Each % is a new keyframe.

@keyframes 'my-animation' {
  0% {
    left: 0;

  50% {
    left: 250px;

  100% {
    left: 500px;

Above are 3 keyframes under the name my-animation. These frames occur at 0%, 50%, and 100% of the animation. Each simply moves an element by setting it’s left property to a new value.

It’s not the most complex animation, but it illustrates the basics of defining @keyframes.

Every keyframe animation must have a rule for 0% (from) and 100% (to) or else it’s invalid. The “from” and “to” keywords can be used instead of the % values. Any properties inside the individual keyframes that can’t be animated are ignored.

The keyframes can be specified in any order, though the sequence will proceed from 0% to 100% as expected. All selectors and values are first determined and sorted in increasing order of time.

You’re not limited to defining one @keyframes rule. Multiple @keyframes can be defined and called in a single document. However @keyframes don’t cascade so an animation will never derive keyframes from more than one @keyframes rule.

Animation states specified by keyframes

Animation Behavior

Animations are what happens between keyframes and they’re similar to transitions in that they change css properties over time with the following key differences.

  • Transitions trigger implicitly when a property changes values. The property change causes the transition.
  • Animations are explicitly executed when animation properties are applied. The animation causes the property change.

Because of the latter explicit values for any properties being animated are required.

During an animation the computed values of properties are controlled by the animation. These computed values override other values that may have been set. Before and after animations those other values will apply.

Animation Properties

The @keyframes rule above defines the change that will happen over the animation.

Most of the properties below are applied to the element(s) that will undergo that animation. They determine which animation to use and how it will be applied.

There are 7 animation properties and some should look familiar if you’ve spent any time with transitions.

  • animation-name
  • animation-duration
  • animation-timing-function
  • animation-iteration-count
  • animation-direction
  • animation-play-state
  • animation-delay

And of course there will be a shorthand animation property combining all of the above.

animation-name property

The animation-name property defines a list of animations that are applied. It’s used to select which @keyframes will apply to an element.

div {
  animation-name: my-animation;

The above sets the @keyframes my-animation as the one to use to animate the div.

animation-duration property

Like transition-duration, the animation-duration property defines the length of time over which the entire animation will run. Naturally it takes a time as its value and its default value is 0 or an instant change.

div {
  animation-duration: 5s;

'Haouse under the star' clock

animation-timing-function property

The animation-timing-function property describes how the animation progresses and it works the same as transition-timing-function with the same values

  • ease
  • linear
  • ease-in
  • ease-out
  • ease-in-out
  • cubic-bezier

I’ll refer you to my post on transitions for specifics of how each of the above works.

If the timing function is applied to the element it sets the timing over the entire animation, however the timing function can also be set on individual keyframes, which would only affect the timing from that keyframe to the next.

@keyframes 'my-animation' {
  0% {
    left: 0;
    animation-timing-function: ease-in;

  50% {
    left: 250px;
    animation-timing-function: ease-in-out;

  100% {
    left: 500px;
    animation-timing-function: linear;

animation-iteration-count property

Transitions run once when some event occurs. Animations can be set to run multiple times. The animation-iteration-count property defines how many times to run the animation sequence.

Its value is a number with the default being 1. A value of infinite means to run the animation forever in an endless loop and a negative value becomes 0.

A non-integer number can be used and will lead to animation ending part way through a cycle. For example setting animation-iteration-count to 2.5 will run the animation 2 ½ times, finishing right in the middle of a cycle.

div {
  animation-iteration-count: 9;

The above will run the animation 9 times before stopping.

An arrow shaped sign with the word 'Art' displayed and pointing left

animation-direction property

The animation-direction property defines whether or not the animation should run in reverse during alternate cycles. It takes 2 values normal (default) or alternate.

div {
  animation-direction: alternate;

The above would set odd numbered iterations to proceed in normal direction and even numbered iterations to proceed in reverse or the alternate direction

Alternate also reverses the timing-functions so ease-in played in reverse becomes ease-out during the alternate direction.

animation-play-state property

You can define if the animation is running or paused (the 2 values) with the animation-play-state property.

div {
  animation-play-state: paused;

A paused animation continues to display the current value of animation until resumed where the resumed animation will then start at that current display.

animation-delay property

As you’d expect the animation-delay property defines when the animation will start. It works exactly the same as transition-delay.

div {
  animation-delay: 0.5s;

The above delays the start of the animation for ½ second.

animation shorthand

Like usual you don’t need to specific all the above properties separately, but can use the shorthand. The shorthand takes the following order.

[<animation-name> | <animation-duration> | <animation-timing-function> | <animation-delay> | <animation-iteration-count> | <animation-direction>] [, [<animation-name> | <animation-duration> | <animation-timing-function> | <animation-delay> | <animation-iteration-count> | <animation-direction>] ]

Multiple animations are separated by a comma.


Animation Events

You can use Javascript to control some aspects of an animation such as whether or not the animation is running or paused. There are 3 animation related events sent to the DOM.

  • animationstart — occurs at the start of the animation
  • animation end — occurs when the animation finishes
  • animation iteration — occurs at the end of each iteration of an animation for which animation-iteration-count is greater than one

Each of the above events has 3 significant properties.

  • event.animationName
  • event.elapsedTime

The event handler can determine the current iteration through a counting mechanism.

With the above in mind you can do things like pause and run an animation with a button click.

Additional Resources

Unlike my simple animation demo there are some really good examples of using css animations on web pages. Here are a couple of collections of examples. There’s a lot of repeat between them.

Here’s a really good post on making your animations look more realistic. It covers some basic principals of animation and shows how to apply them using the css described throughout this post.

Johannes Tonollo has recently put up a site called Meaningful Transitions, which seeks to apply principles to animation in user interface design.

Storyboard for 2 people in a restaurant


CSS animations aren’t quite everywhere online yet. Browser support is getting closer, but still needs more support, and let’s face it not every page needs to be or should filled with moving parts.

Like transitions though, animations should not be applied to critical design elements and so while browser support may not be completely there you can still use animations to communicate non-critical information or just to have some fun.

Where appropriate they can be a nice addition to a web page. While the properties and keyframes above can be combined to created some complex animations, I hope you can see that it’s not to hard to use them for some simple animations.

Have you experimented with css animations or used them in practice? If so where have you found they work best? How have you used them?

« »

Download a free sample from my book, Design Fundamentals.


  1. Great article Steve I have read the most of your CSS articles and are the best.

    One interesting thing I have noticed, is that you can change the order of the shorthand properties:

    from this(normal order):
    div {
    -webkit-animation: myanimation 1s ease-in 2s infinite alternate;

    to this:
    div {
    -webkit-animation: 1s myanimation 2s infinite ease-in ;

    But you can’t put the duration or the animation-name out of the first or second place, otherwise doesn’t work. Maybe this is just in webkit browsers.

    • Thanks Alessandro. Interesting about the order in the shorthand. I just stuck using the suggested order and didn’t try reordering anything. I would think the most important aspect is not reversing the two time durations, since there would be no way for a browser to sort that out.

Leave a Reply

Your email address will not be published.