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.