CSS Animations

CSS animations allow elements to animate.

Basic Animation

The example below changes the colour of a <div> element.

Example of basic transitions (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes colour_change
{
   from 
   {
    background-color : red;
   }
   to 
   {
    background-color : blue;
   }
}

div.animated
{
   background-color : red;
   width : 100px;
   height : 100px;
  
   animation : colour_change 5s; 
}
</style>
</head>

<body>
<div class = "animated"></div>
</body>
</html>

Animation Fill Mode

By default, an element will only take on its animation effects only during the animation. In this case, we need to ensure that the first keyframe and last keyframes match the original state of the element. Otherwise, we shall get a visually displeasing effect, as the element will suddenly change from its normal state to its animated state. This can be seen in the example above.

To ensure that the animated state matches the normal state, use the

animation-fill-mode : both;

Other animation-fill-mode options include:

animation-fill-mode : backwards;  /* Return to normal state after animation */
animation-fill-mode : forwards; /* Stay in final keyframe state after animation */

The example below uses animation-fill-mode-both to keep the <div> blue after the animation. Note that the original red colour of the <div> needs only be declared in the first animation frame. This is in keeping with good programming practice, as we do not repeat any code.

Example of Animation-fill-mode-both (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes colour_change
{
   from 
   {
    background-color : red;
   }
   to 
   {
    background-color : blue;
   }
}

div.animated
{
    /* background-color : red; We now only need to set the initial colour in the first keyframe */
    width : 100px;
    height : 100px;
  
    animation : colour_change 5s; 

animation-fill-mode: both;  
}
</style>
</head>

<body>
<div class = "animated"></div>
</body>
</html>

Animation Keyframes

In the example below, the <div> has three keyframes to control its colour change.

Example of multiple colour changes animation (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes colour_change
{
   0%
   {
    background-color : red;
   }
   50%
   {
    background-color : blue;
   }
   100%
   {
    background-color : orange;
   }
}

div.animated
{
   width : 100px;
   height : 100px;
  
   animation : colour_change 5s both; 
}
</style>
</head>

<body>
<div class = "animated"></div>
</body>
</html>

Animation Parameters

The example below uses the complete set of animation parameters.

Example of a complete set of animation parameters (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes simple_animation
{
   0%
   {
    background-color : red;
    width : 100px;
    height : 100px;
    left : 0px;
    top : 0px;
   }
   50%
   {
    background-color : blue;
    width : 200px;
    height : 400px;
    left : 300px;
    top : 300px;
   }
   100%
   {
    background-color : yellow;
    width : 400px;
    height : 200px;
    left : 300px;
    top : 300px;
   }
}

div.animated
{
   position: absolute;
   
   animation-name: simple_animation;
   animation-delay: 3s;
   animation-duration: 10s;
   animation-timing-function: ease;
   animation-iteration-count: infinite;
   animation-direction: alternate;
   animation-play-state: running;
   animation-fill-mode:both;   
}
</style>
</head>

<body>
<div class = "animated"></div>
</body>
</html>

Combining Animation Parameters using Shorthand

The various animation parameters can be combined into a single line, as per the example below.

Example combining aninmation parameters using shorthand (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes simple_animation
{
   0%
   {
    background-color : red;
    width : 100px;
    height : 100px;
    left : 0px;
    top : 0px;
   }
   50%
   {
    background-color : blue;
    width : 200px;
    height : 400px;
    left : 300px;
    top : 300px;
   }
   100%
   {
    background-color : yellow;
    width : 400px;
    height : 200px;
    left : 300px;
    top : 300px;
   }
}

div.animated
{
   position: absolute;
   animation: simple_animation 10s 1s ease alternate infinite;
}
</style>
</head>

<body>
<div class = "animated"></div>
</body>
</html>

Animate Text

To animate text, place the text in a <div> and animate the <div>. To change the size of the text, either scale the <div> or change the font-size of the text. The example below animates text.

Example of text animation (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes simple_animation
{
   0%
   {
      font-size : 20px;
      color : red;
      top : 0px;
      left : 0px;
   }
   50%
   {
    font-size : 100px;
    color : blue;    
    left : 300px;
    top : 300px;
    transform : scaley(-1);
   }
   80%
   {
    font-size : 50px;
    color : green;
    left : 300px;
    top : 300px;
    transform : rotate(45deg);
   }
   100%
   {
      font-size : 20px;
      color : red;
      top : 0px;
      left : 0px;
   }   
}

div.animated
{
   position: absolute;

   animation: simple_animation 10s both 1s linear infinite normal;
}
</style>
</head>

<body>
<div class = "animated">DkIT</div>
</body>
</html>

Animating an Image

An animation can be applied directly to an <img> element. The example below shows an image animation.

Example of an image animation (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes simple_animation
{
   0%
   {
      width : 100px;
      height : 100px;
      top : 0px;
      left : 0px;
   }
   50%
   {
      width : 300px;
      height : 200px;
      left : 300px;
      top : 300px;
      transform : scaley(-1);
   }
   80%
   {
      width : 200px;
      height : 300px;
      left : 300px;
      top : 300px;
      transform : rotate(45deg);
   }
   100%
   {
      width : 100px;
      height : 100px;
      top : 0px;
      left : 0px;
   }   
}

img.animated
{
   position: absolute;

   animation : simple_animation 10s both 1s linear infinite normal;

}
</style>
</head>

<body>
<img class = "animated" src="images/logo_a.gif">
</body>
</html>

We can animate video in the same way as we animate text or images. Write code to animate a video, as shown here.

Write code to animate an image on top of another image, as shown here.

Add to the code above, so that the top image spins as part of its animation, as shown here.

Write code to fade an image over another image, as shown here.

Combining Animations

We can combine as several animations. The example below combine a text and an image animation.

Example of combined text and image animation (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes image_animation
{
   0%
   {
      width : 100px;
      height : 100px;
      top : 0px;
      left : 0px;
   }
   50%
   {
      width : 300px;
    height : 200px;
    left : 300px;
    top : 300px;
    transform : scaley(-1);
   }
   80%
   {
      width : 200px;
    height : 300px;
    left : 300px;
    top : 300px;
    transform : rotate(45deg);
   }
   100%
   {
      width : 100px;
      height : 100px;
      top : 0px;
      left : 0px;
   }   
}


/* Text animation keyframes */
@keyframes text_animation
{
   0%
   {
      font-size : 20px;
      color : red;
      top : 0px;
      right : 0px;
   }
   50%
   {
    font-size : 100px;
    color : blue;    
    top : 200px;
    right : 400px;
   }
   80%
   {
    font-size : 50px;
    color : green;
    top : 300px;
    right : 600px;
    transform : rotate(45deg);
   }
   100%
   {
      font-size : 20px;
      color : red;
      top : 0px;
      right : 0px;
   }   
}

/* Control the image animation */
img.animated_image
{
   position: absolute;
   animation : image_animation 10s both 1s linear infinite normal;   
}

/* Control the text animation */
div.animated_text
{
   position: absolute;
   animation : text_animation 10s both 1s linear infinite normal;
}
</style>
</head>

<body>
<div class = "animated_text">Welcome To DkIT</div>
<img class = "animated_image" src = "images/logo_a.gif">

</body>
</html>

Write code to cause the text animation to delay for five seconds during each animation loop, as shown here.

Splitting Animated Text

The various characters that make up some text can be animated seperately once they are held in separate container elements. In the example below, we hold each character in a <li> container element.

The example below uses a cubic-bezier(1,0,1,0) transition, which causes most of the animation to occur toward the start of the animation. By placing the initial position of the text to be offscreen, we perform most of the animation offscreen. A seperate timer is used to control each character. Fly-in text effects can be got by changing the transition function. This can be further played with by changing the initial text location to left, right or bottom.

Example of typed text (Run Example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>

@keyframes typing 
{
   from 
   { 
      top:-1000px;   /* Initial position is offscreen */
   }
   to
   {
      top:300px;  
   }
}



div.typing_text li
{
    list-style-type: none;

    position:relative;        
    float:left;

    font-size:50px;
     
    animation: typing 1s cubic-bezier(1,0,1,0) both;                              
}

#delay1
{
    animation-delay:1s;
}

#delay2
{
    animation-delay:2s;
}

#delay3
{
    animation-delay:3s;
}
</style>
</head>

<body>
<div class = "typing_text">
<ul>
    <li>D</li>
    <li id = "delay1">k</li>
    <li id = "delay2">I</li>
    <li id = "delay3">T</li>
</ul>
</div>
</body>
</html>

Manipulate the code above so that the characters drop in from the top of the screen, as shown here.

Manipulate the code above so that the characters slide in from the left of the screen, as shown here.

Write code to get the characters to appear in front of and then to slot into place, as shown here.

Splitting Animated Images

Similarly to the animation of characters, we need to be able hold the various split parts of the image in separate container elements. Again, we can use <li> as a container.

The example below splits an image into four quaters and animates each quater onto the screen in turn.

In order to achieve this animation

Example of split animated image (Run example)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
@keyframes sub_image_1_animation 
{
   from 
   { 
      top:-500px;   /* Initial position is offscreen */
   }
   to
   {
      top:0px;  
   }
}

@keyframes sub_image_2_animation
{
   from 
   { 
      top:-500px;   /* Initial position is offscreen */
   }
   to
   {
      top:0px;  
   }
}

@keyframes sub_image_3_animation
{
   from 
   { 
      top:-500px;   /* Initial position is offscreen */
   }
   to
   {
      top:50%;  
   }
}

@keyframes sub_image_4_animation
{
   from 
   { 
      top:-500px;   /* Initial position is offscreen */
   }
   to
   {
      top:50%;  
   }
}

#container_sub_image_1
{
  top : 0%;
    left : 0%;      

    animation: sub_image_1_animation 1s both linear;       
}

#container_sub_image_2
{
  top : 0%;
    left : 50%; 

    animation: sub_image_2_animation 1s both 1s linear;
}

#container_sub_image_3
{
  top : 100%;
    left : 0%; 
  
    animation: sub_image_3_animation 1s both 2s linear;
}

#container_sub_image_4
{
  top : 100%;
    left : 50%; 

    animation: sub_image_4_animation 1s both 3s linear;
}

#sub_image_1
{
  margin-top:0%;
  margin-left:0%;
}

#sub_image_2
{
  margin-top:0%;
  margin-left:-100%;   /* minus values for image margin will pull the visible image in that direction */
}

#sub_image_3
{
  margin-top:-100%;
  margin-left:0%;
}

#sub_image_4
{
  margin-top:-100%;
  margin-left:-100%;
}

#container_full_image li 
{
    list-style-type: none;  /* remove bullet from list items */                     
}

#container_full_image
{
  position:absolute;
  top:200px;            /* Position on the screen that the image will animate to */
  left:400px;
}


/* Image and container need to be the same size */
#container_full_image,
#container_full_image img
{
  width : 400px;     /* IMPORTANT: For this animation, the width and height must be equal */
  height : 400px;    /* They do not need to be of size 400px */
}

#container_full_image div
{
  position:absolute;
  width:50%;
  height:50%;  
  overflow:hidden;
}
</style>
</head>

<body>
<div id = "container_full_image">
<ul>
  <li><div id = "container_sub_image_1"><img id = "sub_image_1" src="images/logo_a.gif"></div></li>
  <li><div id = "container_sub_image_2"><img id = "sub_image_2" src="images/logo_a.gif"></div></li>
  <li><div id = "container_sub_image_3"><img id = "sub_image_3" src="images/logo_a.gif"></div></li>  
  <li><div id = "container_sub_image_4"><img id = "sub_image_4" src="images/logo_a.gif"></div></li>    
</ul>
</div>
</body>
</html>

Write code to animate an image as four columns, as shown here.

Write code to animate an image as ten rows, as shown here.

The code above is not scalable, as it requires us to cut-and-paste code to give more rows. Use php to write code to split an image into 100 rows that will be displayed over a five second period, as shown here.

Solution to PHP example above:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?php
    $numberOfRows = 100;
    $duration = 5;

    $delay = 0;
    $delayIncrement = $duration / $numberOfRows;
    echo("<style>");
    for ($i = 0; $i < ($numberOfRows); $i++)
    {
        echo("#container_sub_image_" . $i);
        echo("{ top : " . ($i) * (100 / $numberOfRows) . "%;");
        echo("left : 0%;  animation: sub_image_animation 1s both " . $delay . "s linear; } ");

        echo "#sub_image_" . $i . " { margin-top:-" . ($i) * (100 / $numberOfRows) . "%; margin-left:0%; } ";
        $delay += $delayIncrement;
    }
    echo("</style>");
    ?>


<style>
@-webkit-keyframes sub_image_animation 
{
    from 
    { 
        left:-1500px;   /* Initial position is offscreen */
    }
    to
    {
        left:0px;  
    }
}


#container_full_image li 
{
    list-style-type: none;  /* remove bullet from list items */                     
}

#container_full_image
{
    position:absolute;
    top:200px;            /* Position on the screen that the image will animate to */
    left:400px;
}


/* Image and container need to be the same size */
#container_full_image,
#container_full_image img
{
    width : 500px;    
    height: 500px;   
}

#container_full_image div
{
    position:absolute;
    width:100%;
    <?php
    echo " height:" . (100 / $numberOfRows) . "%; ";
    ?>
    overflow:hidden;
}
</style>
</head>

<body>
<div id = "container_full_image">
<ul>
    <?php
    for ($i = 0; $i < ($numberOfRows); $i++)
    {
        echo "<li><div id = 'container_sub_image_" . $i . "'><img id = 'sub_image_" . $i . "' src='city.jpg'></div></li>";
    }
    ?>

</ul>
</div>
</body>
</html>
 
<div align="center"><a href="../../versionC/index.html" title="DKIT Lecture notes homepage for Derek O&#39; Reilly, Dundalk Institute of Technology (DKIT), Dundalk, County Louth, Ireland. Copyright Derek O&#39; Reilly, DKIT." target="_parent" style='font-size:0;color:white;background-color:white'>&nbsp;</a></div>