Learn CSS animation by creating pure CSS loaders
Andreas

Andreas @devmount

About: freelancing software engineer. javascript. php. python. css. husband. dad². guitarero. climber. retrogamer.

Location:
Berlin, Germany
Joined:
Aug 26, 2017

Learn CSS animation by creating pure CSS loaders

Publish Date: Nov 26 '19
910 34

You always wanted to learn the essentials of CSS animations? Me too! Let's do it together in 5 minutes by creating some pure CSS loading animations.

Before we start

CSS animations are already some years old. Browser support is completely given for the current versions of all major browsers. We will cover a fallback for older browsers at the end of this tutorial.

The syntax

Let's dive directly in by looking at the following example:

<!-- HTML -->
<div class="simple-spinner"></div>
Enter fullscreen mode Exit fullscreen mode
/* CSS */
.simple-spinner {
  height: 48px;
  width: 48px;
  border: 5px solid rgba(150, 150, 150, 0.2);
  border-radius: 50%;
  border-top-color: rgb(150, 150, 150);
  animation: rotate 1s 0s infinite ease-in-out alternate;
}
@keyframes rotate {
  0%   { transform: rotate(0);      }
  100% { transform: rotate(360deg); }
}
Enter fullscreen mode Exit fullscreen mode
// RESULT
Enter fullscreen mode Exit fullscreen mode

Looks pretty cool already! What's happening here? First we build a ring by giving a <div> the same width and height, a border where one single side has a different color and applying a border-radius of 50%. To apply an animation, we see two things:

  1. Define the animation property on the element we want to animate
  2. Define a @keyframes rule

The animation property

animation is a shorthand property to set multiple animation properties at once. Let's take the example above and look at them in detail:

example property description
rotate animation-name the name of the animation to use
1s animation-duration how long one animation cycle lasts
0s animation-delay how long to wait for the animation to start
infinite animation-iteration-count how many times the animation should be repeated
ease-in-out animation-timing-function how an animation progresses in one cycle
alternate animation-direction animate forwards, backwards or alternating back and forth.

This means, we specified an animation called "rotate", one cycle (360°) lasts one second, there is no start delay, the animation itself lasts forever, animation progress is not linear and it alternates back and forth (every second cycle is backwards).

Note: To be complete, there are also animation-fill-mode and animation-play-state, but we won't cover those two properties in this tutorial.

The @keyframes rule

Now let's come to the part, where the animation is actually created. With the help of @keyframes, you can specify states along the animation timeline. For each state, you can define when to appear (a percentage of the animation time) and which style declarations to apply.

Our example above animates from 0% transform: rotate(0); (no rotation) to 100% transform: rotate(360deg); (one complete rotation).

Of course the same @keyframes rule can be used by multiple elements. Here is an example of two elements with a different animation rule, using the same @keyframes declaration:

<!-- HTML -->
<div class="double-spinner"></div>
Enter fullscreen mode Exit fullscreen mode
/* CSS */
.double-spinner {
  height: 48px;
  width: 48px;
  border: 5px solid rgba(150, 150, 150, 0.2);
  border-radius: 50%;
  border-top-color: rgb(150, 150, 150);
  animation: rotate 1s 0s infinite linear normal;
}
.double-spinner::after {
  content: '';
  height: 40%;
  width: 40%;
  display: block;
  margin: 10px auto;
  border: inherit;
  border-radius: inherit;
  border-top-color: inherit;
  animation: rotate .5s 0s infinite linear reverse;
}
@keyframes rotate {
  0%   { transform: rotate(0);      }
  100% { transform: rotate(360deg); }
}
Enter fullscreen mode Exit fullscreen mode
// RESULT
Enter fullscreen mode Exit fullscreen mode

For the start and end states (0% and 100%) you can also use the keywords from and to like this:

@keyframes rotate {
  from { transform: rotate(0);      }
  to   { transform: rotate(360deg); }
}
Enter fullscreen mode Exit fullscreen mode

Let's look at an example with some more states:

<!-- HTML -->
<div class="flip-walker"></div>
Enter fullscreen mode Exit fullscreen mode
/* CSS */
.flip-walker {
  width: 64px;
  height: 64px;
}
.flip-walker::before {
  content: '';
  display: block;
  width: 50%;
  height: 50%;
  background: rgba(150, 150, 150, .5);
  animation: flip 2s 0s infinite ease normal;
}
@keyframes flip {
  0%   { transform: translate(0, 0)       rotateX(0)       rotateY(0);      }
  25%  { transform: translate(100%, 0)    rotateX(0)       rotateY(180deg); }
  50%  { transform: translate(100%, 100%) rotateX(-180deg) rotateY(180deg); }
  75%  { transform: translate(0, 100%)    rotateX(-180deg) rotateY(360deg); }
  100% { transform: translate(0, 0)       rotateX(0)       rotateY(360deg); }
}
Enter fullscreen mode Exit fullscreen mode
// RESULT
Enter fullscreen mode Exit fullscreen mode

Here we applied some CSS transformations in five different states, to animate a flipping square.

Multiple animations

It's possible to apply multiple animations to the same element. If we want to make our flipping square from above glow at the same time, we can simply add another animation separated by comma:

/* CSS */
.flip-walker::before {
  /* ... */
  animation:
    flip 2s 0s infinite ease normal,
    glow 2s 0s infinite linear normal;
}
@keyframes flip {
  /* ... */
}
@keyframes glow {
  to { background: white; box-shadow: 0 0 15px white; }
}
Enter fullscreen mode Exit fullscreen mode
// RESULT
Enter fullscreen mode Exit fullscreen mode

Note: I only used the to rule and left the from rule out. This is possible because browsers will use the element's existing/initial styles for the missing start or end states.

Custom timing function

If you're not happy with the default timing functions, you have the possibility to define your own with the help of a cubic-bezier curve. There are a lot of tools to define such a curve, I'm mostly using this one by Matthew Lein.

And here comes the last example of this tutorial:

<!-- HTML -->
<div class="pulse"></div>
Enter fullscreen mode Exit fullscreen mode
/* CSS */
.pulse {
  width: 64px;
  height: 64px;
  background: white;
  border-radius: 50%;
  animation: pulse 1s 0s infinite cubic-bezier(0.000, 1.010, 0.5, 1.200) normal;
}
@keyframes pulse {
  from { transform: scale(0);   opacity: 1; }
  to   { transform: scale(1.0); opacity: 0; }
}
Enter fullscreen mode Exit fullscreen mode
// RESULT
Enter fullscreen mode Exit fullscreen mode

The timing function was just replace by the cubic-bezier(0.000, 1.010, 0.5, 1.200) I created.

Fallbacks

If you want to provide support especially for older browsers, you can use the @supports at-rule for a feature query and provide a fallback e.g. as a GIF. Here is a simplified example:

/* CSS */
.animated {
  background: url(animation-as.gif);
}
@supports (animation-name: test) {
  .animated {
    background: none;
    animation-name: test;
    /* ... */
  }
  @keyframes test {
    /* ... */
  }
}
Enter fullscreen mode Exit fullscreen mode

Browsers that don't support the animation-name property or even the @supports rule will simply show the GIF image as background of your element.

Wrap it up

With the help of some simple CSS loading animation examples on a single element we've seen how to create CSS animations, define different animation states, use multiple animations and create custom timing functions. That's everything you need to create your own awesome CSS animations! 🔥

In case you want to play with the above examples, I put them together in this pen. If you have any questions or want to share your creation, feel free to post a comment.


Published: 26th November 2019
Cover Image: https://codepen.io/devmount/full/NWWZKEN

Comments 34 total

  • Milos
    MilosNov 26, 2019

    Nice article!

    • Andreas
      AndreasNov 26, 2019

      Thank you! 😊 I'm glad if it's helpful!

  • webdeasy.de
    webdeasy.deNov 26, 2019

    Very cool! :)

    • Andreas
      AndreasNov 26, 2019

      Many thanks! 😊

  • Albert Rayneer
    Albert RayneerNov 26, 2019

    Really Nice, it inspired me a lot. Thank you. Stay focused and good job <3

    • Andreas
      AndreasNov 26, 2019

      Thank you for your kind words! So glad that this post is an inspiration for you! 👌🏻

  • Conor Kelly
    Conor KellyNov 26, 2019

    I like it, nice article

    • Andreas
      AndreasNov 26, 2019

      Thank you! 😊

  • Morado
    MoradoNov 26, 2019

    Great!

  • Diego Oliveira
    Diego OliveiraNov 26, 2019

    Awesome article! It opened my mind to new possibilities I didn't realize before!

    • Andreas
      AndreasNov 26, 2019

      That's great! So glad that it's helpful for you!

  • Usama Umar
    Usama UmarNov 26, 2019

    Thank You...

    • Andreas
      AndreasNov 26, 2019

      You're very welcome 😊

  • Mohammed Asker
    Mohammed AskerNov 26, 2019

    I was worried learning CSS animation will be pain in the neck and delay it as long as possible. But you make it surprisingly simple! So thanks, Andreas!

    • Andreas
      AndreasNov 26, 2019

      I'm so glad that it's useful for you! 😊

  • David Sanchez
    David SanchezNov 26, 2019

    Great article and animations!

    • Andreas
      AndreasNov 26, 2019

      I'm glad you like it!

  • Łukasz Sarzyński
    Łukasz SarzyńskiNov 26, 2019

    Beautiful examples !

    • Andreas
      AndreasNov 26, 2019

      Many thanks! 😊

  • Ravavyr
    RavavyrNov 26, 2019

    Nicely done, really like the "glow" one. So simple, but so effective :)

    • Andreas
      AndreasNov 26, 2019

      Thank you! That's what I love about CSS: You can create awesome effects with just a couple of rules!

  • Frank
    FrankNov 26, 2019

    This is one of those things that you ~know~ you can do with css, but you made it look so simple! I'm going to make myself a set of these for fun and to copy-pasta in the future! Thanks!

    • Andreas
      AndreasNov 26, 2019

      Awesome! Don't forget to share your creations with us :)

  • Tejas Srivastava
    Tejas SrivastavaNov 27, 2019

    Awesome 👍

    • Andreas
      AndreasNov 27, 2019

      Thank you! 😊 Glad You like it!

  • dongyu
    dongyuNov 28, 2019

    really like

  • NLSanyu
    NLSanyuDec 3, 2019

    Awesome!

    • Andreas
      AndreasDec 3, 2019

      Thank you! 😊

  • Stefan Natter 🇦🇹👨🏻‍💻
    Stefan Natter 🇦🇹👨🏻‍💻May 21, 2020

    Thanks, Andreas. I'm just starting to invest more time animating elements and your tutorial was super helpful. Thanks!

    • Andreas
      AndreasMay 21, 2020

      You're very welcome, that's great! 👏🏻
      Let us know if you have something to show!

  • Ivan Arcos
    Ivan ArcosAug 2, 2020

    Hello, again, Andreas! 👋🏻

    I’m looking for some hover effects changing color in plain text with smooth transition, could you help me? 🙂

    • Andreas
      AndreasSep 17, 2020

      Hi Ivan, sorry for the late response. What exactly are you trying to achieve? What have you tried so far?

Add comment