| Coding Tutorials

Introduction to Animation in CSS

CSS Animations give your site and/or brand a unique touch, provide more accessibility, help create affordance (the perception about how an element inside the design is to be used), and can provide the user with a better experience. All this happens when animations are designed and used the right way.

Subtle animations in a web site, point the user to certain tasks to be accomplished, like clicking a call-to-action link or filling out a form. Other animations, like a loading icon inside a button, make the user understand what they need to do, like wait while the next page loads.

This tutorial will explain the concept of animations with a simple example. Let’s start!


CSS Animations

CSS animations allow you to change the initial style of an element to another different style over a span of time. The definition of the animation in the CSS code has two parts: 

  • The description of the animation — how the animation is going to perform over time. This is done with the @keyframes rule.
  • The definition of the animation — how the animation will change the style of the targeted element and how long it is going to take, to perform the whole animation sequence. You use the animation property and all its sub-properties for that.   

The @keyframes rule

Each keyframe will show how an animated element will be presented (rendered to the viewer) in a determined moment over a period of time.

There are only 2 mandatory keyframes; the one, which points at the start of the animation sequence, and the one pointing to the end of it. Those values are represented by 0% and 100%. These values have also the keywords from and to. You can use these keywords instead of the percentage values, or you can omit them at all. You can even mix a keyword with a percentage value if you would like to.

@keyframes myanimation {
0% {background-color: rgb(243, 243, 65);}
to {background-color: rgb(251, 179, 45);}
}



Notice the use of a custom name to call the animation. This name will be defined within the element’s styles. As you can see, this animation sequence has only a starting and an ending point, that is, there are no other keyframes between. You could place a keyframe at half the way. 

@keyframes myanimation {
0% {background-color: rgb(243, 243, 65);}
50% {background-color: rgb(243, 83, 25);}
to {background-color: rgb(251, 179, 45);}
}




The animation property

As already stated, the animation property has multiple sub-properties. The 2 required ones are: 

  • animation-name
  • animation-duration
a {
/* Animation styles */
animation-name: myanimation;
animation-duration: 2s;
/* Other styles */
display: inline-block;
border: 3px solid rgb(62, 62, 241);
border-radius: 10px;
padding: 1em;
color: rgb(62, 62, 241);
}



You define the name of the animation with the animation-name property. You bind the animation of the object to the keyframes you described through the name. The other mandatory property in an animation is the animation-duration property, that is, the time span, that the whole sequence is going to take (in this case 2 seconds). 

  • Create an HTML file with an <a> tag and ink this CSS file to it
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>CSS Animations</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<div class="container">
<a href="#">Read more</a>
</div>
</body>
</html>

 

Every time you refresh the page, the animation will play.

ccs animations

The link turns from its original white background color to yellow, after 1 second, the background changes to dark orange. 

When the sequence ends, the background of the button changes to the last specified color (light orange), and after that turns immediately into the original white background. Notice that there is no transition between the background changes at the beginning and at the end of the animation. 

  • Edit the CSS code:
a {
/* Animation styles */
animation-name: myanimation;
animation-duration: 2s;
animation-delay: 1s;
/* Other styles */
display: inline-block;
border: 3px solid rgb(62, 62, 241);
border-radius: 10px;
padding: 1em;
color: rgb(62, 62, 241);
}



The animation-delay property sets the animation to start 1 second after page refresh.

Edit the code one more time:

a {
/* Animation styles */
animation-name: myanimation;
animation-duration: 2s;
animation-delay: 1s;
animation-iteration-count: 2;
/* Other styles */
display: inline-block;
border: 3px solid rgb(62, 62, 241);
border-radius: 10px;
padding: 1em;
color: rgb(62, 62, 241);
}

 

With animation-iteration-count, you define how many times the animation is going to be reproduced. In this case wit a value of 2, the animation will start 1 second after refreshing the page and the sequence will play 2 times. You can make an endless animation, by setting the value of animation-iteration-count to infinite.

The animation-direction property sets the way the animation sequence is played. You have four possible values here: 

  • normal — the animation plays forward, the way you configured it. This is the default value.
  • reverse — the animation plays backwards. It starts with the last keyframe and ends with the first one.
  • alternate — the animation is played forward in the odd cycles and backwards in the even cycles (iterations)
  • alternate reverse — the animation is played backwards in the odd cycles and forward in the even cycles
  • Edit the CSS code: 
a {
    /* Animation styles */
    animation-name: myanimation;
    animation-duration: 2s;
    animation-delay: 1s;
    animation-iteration-count: 2;
    animation-direction: alternate-reverse;
    /* Other styles */

    display: inline-block;
    border: 3px solid rgb(62, 62, 241);
    border-radius: 10px;
    padding: 1em;
    color: rgb(62, 62, 241);
}

 
The sequence will be the following:  

white | dark orange | light orange | yellow | white (you will not see this one) | yellow | light orange | dark orange | white — actually it is not white, it just has no background.

 Edit the CSS code: 

a {
    /* Animation styles */
    animation-name: myanimation;
    animation-duration: 2s;
    animation-delay: 1s;
    animation-iteration-count: 2;
    animation-direction: alternate-reverse;
    animation-timing-function: ease-in-out;
    /* Other styles */

    display: inline-block;
    border: 3px solid rgb(62, 62, 241);
    border-radius: 10px;
    padding: 1em;
    color: rgb(62, 62, 241);
}


The animation-timing-function calculates the speed of the animation on each moment of the sequence, which is the acceleration of the animation at that particular moment. By default, the value provided is ease, which provides a slow start of the animation, then it goes faster, and it finishes with a slow end. The value ease-in-out will force the animation to have a slow start and also a slow end. 

  • Edit the HTML file to add another link: 


Now edit the CSS to add a rule for the second link: 

.second {
    animation-timing-function: ease;
}

 

This will give you an idea of the difference between ease and ease-in-out, by comparing both links. 

Other possible values for the animation-timing-function are:

  • linear
  • ease-in
  • ease-out
  • cubic-bezier(n,n,n,n), which lets you define your own set of parameters
  • Edit the CSS code once again: 

a {
    /* Animation styles */
    animation-name: myanimation;
    animation-duration: 2s;
    animation-delay: 1s;
    animation-iteration-count: 2;
    animation-direction: alternate-reverse;
    animation-timing-function: ease-in-out;
    animation-fill-mode: forwards;
    /* Other styles */

    display: inline-block;
    border: 3px solid rgb(62, 62, 241);
    border-radius: 10px;
    padding: 1em;
    color: rgb(62, 62, 241);
}

The animation-fill-mode value lets you configure the appearance of the element, once the animation is finished, or before it starts (if it has an animation delay).  

The value forwards means that the element will keep the last style applied in the @keyframes rule, in this case, the light orange background. 

Add a green background to the button, and change the value of animation-fill-mode

  • Edit the CSS code: 
a {
    /* Animation styles */
    animation-name: myanimation;
    animation-duration: 2s;
    animation-delay: 1s;
    animation-iteration-count: 2;
    animation-direction: alternate-reverse;
    animation-timing-function: ease-in-out;
    animation-fill-mode: backwards;
    /* Other styles */

    display: inline-block;
    border: 3px solid rgb(62, 62, 241);
    border-radius: 10px;
    padding: 1em;
    color: rgb(62, 62, 241);
    background-color: rgb(45, 209, 45);
}


In this case, the element will retain the first keyframe style during the delay and it will turn back to its original style (the added green background color), once the animation has finished. The other possible values for animation-fill-mode are:

  • both — which combines forwards and backwards  
  • none — default value, does nothing

The animation Shorthand

To combine all properties in one practical shorthand, we use the animation property in this order. 

animation: [animation-name] [animation-duration] [animation-delay] [animation-timing-function] [animation-iteration-count] [animation-direction] [animation-fill-mode];

  • Edit the CSS code: 
a {
    /* Animation styles */
    animation: myanimation 2s 3s ease-in-out 2 alternate backwards;
    /* Other styles */

    display: inline-block;
    border: 3px solid rgb(62, 62, 241);
    border-radius: 10px;
    padding: 1em;
    color: rgb(62, 62, 241);
    background-color: rgb(45, 209, 45);   
}

Animating an Icon

Since animating a link with no other purpose than watching it change does not make much sense, we are going to code a button, which will display an icon after hovering it. This icon will rotate for a period of time of half a second, so the user (kind of unconsciously) knows it will take her to the desired target — once again, affordance —.

  • Add Font Awesome to your site. 

The easiest way to do that is through the Font Awesome CDN. Click this link and enter your email address in the input box. The people at Font Awesome will send you an email with the  subject “Your new Font Awesome CDN embed code“, containing a script tag. Paste this tag in the head section of your HTML document right before the link to the stylesheets.

  • Edit the HTML code to add a second button:


Edit the CSS code: 

.second a {
    background-color: rgb(227, 246, 52);
    padding: 1em;
    margin-top: 1em;
}

.second span {
    display: none;
}

@keyframes secondanimation {
    from {display: rotate(0deg);}
    to {transform: rotate(180deg);}
   
}

.second a:hover span {
    animation-name: secondanimation;
    animation-duration: 0.5s;
    display: inline-block; /* Span elements are NOT animatable by default */
    animation-fill-mode: forwards;
}

You just have created a keyframes rule named secondanimation that describes the rotation of the span element. This element will be not displayed on the page until you hover over the link.  


Autoprefixer

To be on the safe side, always use an autoprefixer when you finish writing your code. This will handle inconveniences that could occur with Webkit-based browsers.

 

@-webkit-keyframes secondanimation {
    from {
        display: rotate(0deg);
    }

    to {
        -webkit-transform: rotate(180deg);
        transform: rotate(180deg);
    }

}

@keyframes secondanimation {
    from {
        display: rotate(0deg);
    }

    to {
        -webkit-transform: rotate(180deg);
        transform: rotate(180deg);
    }

}

.second a:hover span {
    -webkit-animation-name: secondanimation;
    animation-name: secondanimation;
    -webkit-animation-duration: 0.5s;
    animation-duration: 0.5s;
    display: inline-block;
    /* Span elements are NOT animatable by default */
    -webkit-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
}

Browser Support

browser support


Other Useful Links

https://daneden.github.io/animate.css/

The code of this exercise can be found here.

We have several classes on CSS topics - check them out. Thanks for reading!  


About the author

Jorge lived in Ecuador and Germany. Now he is back to his homeland Colombia. He spends his time translating from English and German to Spanish. He enjoys playing with Drupal and other Open Source Content Management Systems and technologies.