How to use CSS Animations without a library

August 24, 2020

All visibile elements on a webpage can be animated using CSS Animations. Each CSS animation is declared in an associated @keyframes block which describes the properties that will be transformed during the animation.

Animated elements can be triggered in a variety of ways. They can be run immediately, with a delay, or set off by JavaScript events.

We can try out some animations by creating a index.html file to save and run our code. In this tutorial, we will go over the basics of animations along with 4 examples you can run in the browser for hands-on practice.

First Example: Slide and fade in text

<!DOCTYPE html>
<html>
  <head>
    <title>CSS Animations: Slide/fade in text</title>
    <style>
      h1 {
        animation: slideFadeInRight 2s 1;
        text-align: center;
      }
      @keyframes slideFadeInRight {
        0% {
          opacity: 0;
          transform: translateX(100px);
        }
        100% {
          opacity: 1;
          transform: translateX(0px);
        }
      }
    </style>
  </head>
  <body>
    <h1>CSS Animations Slide and Fade in</h1>
  </body>
</html>

Save this file and open it in the browser. You can do this in most browsers by dragging and dropping the file into a new tab. This animation slideFadeInRight will translateX in a header element while fading-in it’s opacity.


Each HTML element that uses the animation property references a keyframe with it’s animation-name.

Animation properties

In this example we set 3 animation properties: animation-name, animation-duration, and animation-iteration-count to bring in our header.


There are other animation properties that can be changed as well, including

Animation Property Description Example Value
animation-name specifies name of keyframe camelCase characters
animation-duration length of animation 1s / 1000ms
animation-delay length of delay 1s / 1000ms
animation-timing-function type of timing function ease-in, cubic-bezier(.5,.2,.3,.1)
animation-iteration-count number of animation iterations 1, 2, infinite
animation-direction repeat or back-and-forth normal, alternate
animation-fill-mode sets before and after styles forwards, backwards, both, none
animation-play-state allows for pause and resume paused, running

Keyframes

Declare a keyframe with the @keyframes name syntax.

Keyframes can either use the from, to syntax

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

or the percentage % syntax

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  25% {
    transform: rotate(45deg);
  }
  100% {
    transform: rotate(-270deg);
  }
}

Any animated properties are specified between at least two stages of a keyframe.

In a keyframe from or 0% indicate the beginning state of each animated property, while to or 100% indicate the end states. Values in between states get interpolated based on where they are in the animation.

Second Example: Grow and Shrink

<!DOCTYPE html>
<html>
  <head>
    <title>CSS Animations: All Properties</title>
    <style>
      h1 {
        animation-name: growShrink;
        animation-duration: 1.25s;
        animation-timing-function: linear;
        animation-delay: 25ms;
        animation-direction: alternate-reverse;
        animation-iteration-count: infinite;
        animation-fill-mode: both;
        animation-play-state: running;
        text-align: center;
      }
      @keyframes growShrink {
        0% {
          transform: scale(1);
        }
        100% {
          transform: scale(2.5);
        }
      }
    </style>
  </head>
  <body>
    <h1>CSS Animations Grow and Shrink</h1>
  </body>
</html>

Animation shorthand syntax

There are several shorthands that can be used for the animation property including

  • animation: name | duration
  • animation: duration | name | delay | iteration count
  • animation: duration | name | delay | timing-function | iteration-count

The syntax seems to be quite flexible as long as you specify the duration before the delay and make sure to include a animation-name as well as only valid arguments.


Here is another example animation using the animation shorthand proerty

Third Example: Shorthand syntax

<!DOCTYPE html>
<html>
  <head>
    <title>CSS Animations: Shorthand syntax</title>
    <style>
      #object {
        width: 100px;
        height: 100px;
        color: green;
        border: 4px solid orange;
        border-radius: 50%;
        animation: movingColorBall 1.25s infinite ease-in-out;
      }
      @keyframes movingColorBall {
        0% {
          transform: scale(1) translate(100px, 0px);
          background-color: green;
        }
        100% {
          transform: scale(2.5) translate(300px, 200px);
          background-color: red;
        }
      }
    </style>
  </head>
  <body>
    <div id="object"></div>
  </body>
</html>

In this animation we have a growing ball which moves across the screen while changing colors. This example has a keyframe with multiple transform properties.

Multiple transformations

In CSS we can have two transformations occur by separating them with a space. Otherwise if you were to declare them separately, the latter one will overwrite the former (scale would overwrite translate) as seen below

Incorrect example

@keyframes badTransformExample {
  0% {
    transform: translate(50px, 250px);
    transform: scale(1);
  }
  100% {
    transform: translate(300px, 200px);
    transform: scale(2.5);
  }
}

Animatable Properties

  • opacity
  • transform (translate, scale, rotate)
  • color / background-color
  • height / width

There are actually hundreds of properties which can be animated in CSS. A full list can be found here.

Animation Performance

While color and height can be animated, it is generally more performant to use only opacity and transform animations where possible. Animating an element’s height or width can be improved in performance by instead using transform: scale(). .

Fourth Example: Chaining animations

Multiple animations can be chained together using setTimeout in JavaScript. This can be done by adding animation classes to elements on the DOM.

<!DOCTYPE html>
<html>
  <head>
    <title>CSS Animations: chaining multiple animations</title>
    <style>
      h1 {
        text-align: center;
      }
      .opacity-none {
        opacity: 0;
      }
      .slide-in-left {
        animation: slideInLeft 1s 1;
      }
      @keyframes slideInLeft {
        from {
          transform: translateY(-200px);
        }
        to {
          transform: translateY(0px);
        }
      }
      .fade-in {
        animation: fadeIn 1s 1;
      }
      @keyframes fadeIn {
        from {
          opacity: 0;
        }
        to {
          opacity: 1;
        }
      }
    </style>
  </head>
  <body>
    <div style="background-color: gold;">
      <h1 class="opacity-none">CSS Animation Example</h1>
    </div>
    <script>
      var containerEl = document.querySelector('div')
      var headerEl = document.querySelector('h1')
      containerEl.classList.add('slide-in-left')

      setTimeout(function () {
        headerEl.classList.add('fade-in')
        headerEl.classList.remove('opacity-none')
      }, 1000)
    </script>
  </body>
</html>

In this example we set a timer after the gold box drops down. Once the first animation is over, the text fade-in animation begins. You can set as many setTimeout functions as you need to chain together complex animations. Elements can be accessed from the DOM via querySelector and have their classList property adjusted.

Conclusion

There is a tremendous amount you can accomplish with just a few simple keyframes and some setTimeout functions.


While animations can get quite complex and sometimes a library seems simpler, it is always useful to understand techniques for solving problems in plain CSS / JS.

Other CSS Tutorials

JavaScript

Top 10 Apps to Build When Learning Web Development

HTML

Tips for Handling Images in Web Development