The Definitive Guide to CSS Animations and Transitions

January 11, 2012 at 4:00 pm By

How do they work?

The animation and transition tags are summary properties, composed of all the various options you can apply to an animation or transition. They are largely to do with the movement of objects or setting a transition phase to make things appear to be more smooth. Across the internet a wide variety of examples have been composed showing the capabilities that CSS3 and these properties bring to the table.

The Difference

The main difference between an animation and a transition is a transition can only change from one element to another on hover or when an element becomes active, i.e. through a pseudo class. Animations can be initiated from the page loads without any user interaction, but can still be mixed in with user interaction. Both have their own benefits, and are useful in their own unique situations. More complex effects will however require animations, which in turn require keyframes, the syntax of animations.

Support

These features are rather popular, and as such the major browsers have all incorporated experimental support. Opera being the exception, not supporting animation but supporting transitions.

Webkit Gecko Trident Presto
Transition Properties Experimental Experimental Experimental Experimental
Animation Properties Experimental Experimental Experimental Unsupported

Animations

MAIN SYNTAX

Multiple animations are separated by commas. Instead of doing each bit individually, you can do it all at once with the main syntax. Just stick the different parts into animation like below.


animation: [ <animation-name> <animation-timing-function> <animation-delay> <animation-iteration-count> <animation-direction> <animation-fill-mode> ], [apply another animation]

Each option above can be set individually which is quite useful, but this is only useful once you set keyframes. The W3C proposed syntax goes like this:

@keyframes NAME-OF-ANIMATION {
     0% {
          /* CSS for 0% */
     }
     100% {
          /* CSS for 100% */
     }
}

The CSS you put in the 0% bracket will happen immediately as soon as the animation is initiated. The 100% animation is what will happen right at the end. 0% and 100% aren’t required though, you could very easily use 50% { for what happens half way through, or even 46% {. Heck, you don’t even need 2 frames! As you can probably tell, this gives us a lot of flexibility!

However, because of browser compatibility and the fact that these features are still experimental, we need to add browser extensions to the start of each CSS tag. So for example, since animations are supported by Webkit, Firefox and Internet Explorer (platform preview), we write it more like this:


@-webkit-keyframes NAME-OF-ANIMATION {
     0% {
          /* CSS for 0% */
     }
     100% {
          /* CSS for 100% */
     }
}
@-moz-keyframes NAME-OF-ANIMATION {
     0% {
          /* CSS for 0% */
     }
     100% {
          /* CSS for 100% */
     }
}
@-ms-keyframes NAME-OF-ANIMATION {
     0% {
          /* CSS for 0% */
     }
     100% {
          /* CSS for 100% */
     }
}

Notice how we’ve added -moz-, -webkit- and -ms- to the start of the keyframes property. Everything else can be filled in, but remember you’ll have to fill it in multiple times (for now anyway, until it’s totally supported).

After we make up our animation like above, we have to decide what we’re applying it to. So after you’ve added a bunch of styles to the keyframes, pick the div or span you wish to apply the animation to. As mentioned before, there are a bunch of options that help you have more precise control over how the animation works.

• animation-name

As we did earlier, we set a name for the keyframes. So to apply the animation to you need to set 2 animation properties. These are animation-name and animation-duration. As a side note, because (again) browser support is still in the experimental stage, we have to add -moz-, -webkit- or -ms- to the start. So it’s going to look a little something like this:

-webkit-animation-name: name; /* The animation we're running */
-moz-animation-name: name;
-ms-animation-name: name;

Remember, it’s still required that we set the duration and timing function to make the animation work. Multiple animations can be done

• animation-duration

The duration is the length of time you wish to run the animation for, measured in seconds.

-webkit-animation-duration: 1s; /* Runs for 1 second */
-moz-animation-duration: 1s;
-ms-animation-duration: 1s;

• animation-timing-function

The type of timing you wish to apply to the animation. There are various options to choose from including:

  • ease – Slow at start, fast in middle, slow at end
  • linear – Same speed the whole way through
  • ease-in – Slow at start
  • ease-out – slow after
  • ease-in-out – Slow at start and end
  • cubic-bezier(number, number, number, number) – Set another speed based on the cubic bezier function, numbers should be 0 to 1

As an example, we might do:

-webkit-animation-timing-function: ease-in;
-moz-animation-timing-function: ease-in;
-ms-animation-timing-function: ease-in;

• animation-delay

This allows you to delay when the animation starts, so we could delay it by 2 seconds by saying:

-webkit-animation-delay: 2s;
-moz-animation-delay: 2s;
-ms-animation-delay: 2s;

• animation-iteration-count

The number of times the animation will repeat. You can also make it repeat infinitely by using the infinite keyword. Otherwise it’s just a number.

-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-ms-animation-iteration-count: infinite;

• animation-direction

Which direction the animation should proceed in. You can make it play normally with the keyword normal or in alternates (using the keyword alternate) as in it goes forward the first time, it goes backwards the second time, then it goes forward the third time, and so on.

-webkit-animation-direction: alternate; /* Alternating */
-moz-animation-direction: alternate;
-ms-animation-direction: alternate;

• animation-fill-mode

Sets the finishing setting. For example, if you set this to forwards then whatever you defined as the last keyframe. will be what happens at the end of the animation (assuming it doesn’t repeat infinitely). If you set this to backwards then whatever you set as your first keyframe will be how it ends. This is useful for animated hover over effects.

-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-ms-animation-fill-mode: forwards;

Summary Example

As a summary, here’s an example of an animation. In this animation, as soon as the page loads every div will develop a red background over 10 seconds, and stay red until the user refreshes or leaves the page.


@-webkit-keyframes turn-red {
    100% {
         background: red;
    }
}
@-moz-keyframes turn-red {
    100% {
         background: red;
    }
}
@-ms-keyframes turn-red {
    100% {
         background: red;
    }
}

div {
    background: white;
    -webkit-animation: turn-red 10s ease-in forwards;
    -moz-animation: turn-red 10s ease-in forwards;
    -ms-animation: turn-red 10s ease-in forwards;
    -o-animation: turn-red 10s ease-in forwards;
}

Transitions

MAIN SYNTAX

Instead of doing each bit individually, you can do it all at once with the main syntax. Just stick the different parts into transition like below.

transition: [ <transition-property> <transition-duration> <transition-timing-function> <transition-delay> ], [comma separates multiple transitions]

Multiple transitions are defined with commas. Transitions are much more limited than animations. A transition has to take place between two psuedo classes, so for example, a transition is usually set in the main class. So for example, we might have a set of stuff like this:


.main {
   /* transition set here */
}

.main:hover,
.main:active,
.main:focus {
   /* transition will effect this assuming that the correct
      properties are mentioned in the transition phase. */
}

So there are two things you have to define for a transition to work. These being the time and the property you wish to apply the transition to. Generally I apply them in the overall transition tag but we’ll go through them individually, so you can understand!

• transition-property

We still have to add browser specific tags to the start of each property since this stuff is experimental. Don’t forget, Opera supports this feature too! The transition-property is the property which you want to transpire. For example, if you want something fluidly to the left, you would set you’d Alternatively you can say ‘all’ which transitions all properties applied to pseudo elements. In short its the CSS property you want to transit.

-webkit-transition-property: left; /* So it would possibly slide to the right */
-moz-transition-property: left;
-ms-transition-property: left;
-o-transition-property: left;

• transition-duration

The length of time the transition will work over.

-webkit-transition-property: 1s;
-moz-transition-property: 1s;
-ms-transition-property: 1s;
-o-transition-property: 1s;

• transition-timing-function

Similar to what we described in the animation section. Here they are again if you’re feeling lazy:

  • ease – Slow at start, fast in middle, slow at end
  • linear – Same speed the whole way through
  • ease-in – Slow at start
  • ease-out – slow after
  • ease-in-out – Slow at start and end
  • cubic-bezier(number, number, number, number) – Set another speed based on the cubic bezier function, numbers should be 0 to 1

-webkit-timing-function: linear;
-moz-timing-function: linear;
-ms-timing-function: linear;
-o-timing-function: linear;

• transition-delay

Again, the delay before the transition begins, similar to the animation delay.

-webkit-transition-delay: 2s;
-moz-transition-delay: 2s;
-ms-transition-delay: 2s;
-o-transition-delay: 2s;

Summary Example

To summarize, here is an example. In this example any div will change from black text to red text when hovered over. On hovering out, the black text will reappear.

div {
    color: black;
    -webkit-transition: color 2s ease-in;
    -moz-transition: color 2s ease-in;
    -ms-transition: color 2s ease-in;
    -o-transition: color 2s ease-in;
}
div:hover {
    color: red;
}