CSS Animation Basics

Chapter 49 12 mins

Learning outcomes:

Introduction

In the previous CSS Transitions unit we got our hands on transitions and explored various concepts in the way such as timing functions and cubic beziers. CSS transitions and animations operate in much the same way except for only a handful of differences.

If you know transitions well enough, you won't find it hard to learn animations. However if you aren't familiar with transitions, then you should consider learning them first by heading over to Transitions Introduction.

This chapter shall introduce you to CSS animations in general terms of the related properties and then afterwards take you to understanding keyframes. Let's begin animating stuff!

Keyframes for animations

As we know from the previous unit, a CSS transition can only go from an initial state to a final state - there can be no state in between. There is no way we can get it from its initial state to some intermediary state and then from there to the final one.

It is essentially and only a two stage process.

However unlike a transition, an animation has the capability of going across multiple (more than two) states. For example using an animation we can get an element to first move left by 100px and then to the bottom by 100px. A transition can only move it all in one go!

This means that an animation can potentially have multiple states associated to it with their respective styles; and therefore require more code to be laid out than a simple transition. In this connection, developers thought of providing some place to layout these states easily and cleanly in a stylesheet. This is what we know as the @keyframes rule.

For a given animation, the underlying styles for all the states are to be written inside this rule, just like you normally would in a selector block.

Exactly how to write them will be shown to you shortly below.

Now since there can be many animations and @keyframes rules on a single webpage we need a way to bind each rule to a given animation.

This is where an animation name steps in. The name goes in the animation-name property for a selector and after the @keyframes keyword. With this the interpreter is able to relate which @keyframes rule is given for which selector.

Both these ideas are summarised as follows in terms of CSS code:

<selector> {
    animation-name: myAnimation;
    /* all animation configurations like its name, duration,
       timing-function, iteration-count go in the selector's declaration block */
}
                                    
@keyframes myAnimation {
    /* the animation states go here */
    /* all CSS styles involved are written inside this rule */
}

Moving further, inside @keyframes we give further subrules to{}, from{} or percentage{} to layout the various states of an animation i.e initial, final, halfway state and so on.

from{} contains the styles to start the animation with, whereas to{} contains the styles to end it with.

As an example clarifying all this mess of information consider the following.

div {
    width: 100px;
    height: 100px;
    background-color: red;
    position: relative; /* given to make the div movable by property left */
    animation-name: anim1;
    animation-duration: 4s;
}

@keyframes anim1 {
    from { left: 0 }
    to { left: 200px }
}
Try it out

animation-name in line 6 sets an animation on the div which is laid out at lines 10-13 in the @keyframes rule. animation-duration is needed for the animation to start working - or else it would default to 0s and we'll see no animation!

We'll discuss animation-duration in detail below.

from{} contains the styles the animation will start with. In this case it starts with left: 0 (which however is already the case). On the other hand to{} contains the styles the animation will end with. In this case it contains left: 200px and hence the animation will end when the div moves to the right by 200px.

This is a CSS animation!

But this not all about a CSS animation. Next we will discuss further the concepts and ideas involved in animations. Let's dive into it.

Animation Iteration Count

As you already know, a transition can flow between its initial and final states only once; not more than that. In contrast, an animation can keep on repeating for any number of iterations between its initial and final states.

1 iteration means it runs once, 2 means it runs twice (initial to final, then again from the initial to the final state) and so on. It can even run for infinite iterations.

For a given animation this number of iterations is laid out in animation-iteration-count. It can take any positive integer for the number of times the animation should repeat or the value infinite to keep it running forever. If unspecified, the property defaults to 1 i.e a single iteration.

In the example below the div animates only for a single iteration.

div {
    animation-name: anim1;
    animation-duration: 2s;
    animation-iteration-count: 1;
}

Iteration count

Animation Direction

A fairly interesting thing to see in animations is the idea of animation direction.

Suppose you want to start your animation from the final state and go towards the initial state instead of going the normal direction i.e initial to final. You can use animation-direction to your advantage with the value reverse.

reverse simply reverses the animation: everything starts from the final state and goes towards the initial one. Think of the graph of the animation as starting from the end point and approaching the starting point; in that case even the timing function gets reversed:

  1. ease-out becomes ease-in and ease-in becomes ease-out.
  2. ease-in-out, however remains the same due to its shape.
div {
    animation-name: anim1;
    animation-duration: 2s;
    animation-direction: reverse;
}

Reverse animation

Anyways this value isn't the interesting thing we were talking about earlier. That interesting thing is the value alternate.

alternate simply alternates between the directions starting from the initial state. It'll go from initial to final, then from final to initial, then again from initial to final and so on and so forth. In other words it simply oscillates between the animation states.

The effect of alternate can only be seen when the iteration count of the animation is greater than 1.
div {
    animation-direction: alternate;
}

Alternating animation

Another value, alternate-reverse, as the name might suggest, operates exactly like alternate except for that it starts from the final state instead of the initial one i.e starts in the reverse direction.

It is simply a mixture of alternate and reverse.

The least exciting, but the most common and the default value for animation-direction is normal. It denotes the normal, forward direction.

Animation Fill Mode

There are a couple of instances when one wants to let an element stay in the styles an animation left it on, after being completed. What this means is the following.

Suppose that after moving a div to the right by 100px (left: 100px), using an animation, you want it to stay in that position, instead of resetting back to its original position i.e left: 0. What can you do to accomplish this?

Well you can use animation-fill-mode to solve just this problem. Its value forwards serves to maintain the styles with which an animation ends.

div {
    animation-name: anim1;
    animation-duration: 2s;
    animation-fill-mode: forwards;
}

On the other hand, backwards applies the beginning styles of an animation prior to its start. The application of backwards is most noticeable when the animation has a delay setup.

The value both combines forwards and backwards together i.e both the initial and final styles are maintained outside the duration of the animation.

Animation fill mode

Animation Play State

The last difference between a CSS transition and an animation is of being able to play or pause an animation using the property animation-play-state. A transition, however, can not be paused in any way while it is going from its initial state to the final state.

animation-play-state can take two values: one is playing which means that the animation is allowed to be playing whereas the second one is paused which obviously implies that the animation is paused, stopped.

div {
    animation-name: anim1;
    animation-duration: 2s;
    animation-play-state: paused;
}
When an animation is paused using animation-play-state: paused remember that it is paused right at the moment the property is executed by the CSS interpreter.

Duration, Delay and Timing Function

Finally over with the differences, now let's see the similarities between animations and transitions. As you saw transition-duration, transition-timing-function and transition-delay in the previous chapter there exists similar properties for animations too - and they work exactly the same way.

animation-duration specifies the time it takes for an animation to complete.

animation-delay specifies the time by which an animation is delayed before getting started.

animation-timing-function accounts for the rate at which styles are animated with respect to time. It operates similar to transition-timing-function accepting essentially the same values.

Animation duration, delay and function

In conclusion

And this marks the completion of the basics of CSS animations. In the next chapter we shall explore animation keyframes in more detail before moving on to tasting the flavor of browser compatibility in animations.

There were, no doubt, a lot of concepts and ideas relating animations in this chapter and hence it is recommended that you get yourself comfortable with them first before moving over to the next chapters.

Keep practising and keep learning!

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage