Creating Jumping Dots CSS Animation with Examples

We will go over creating a jumping dots animation with CSS. This effect is great for loading type animations!

Dec 17, 2022 | Read time 10 minutes

🔔 Table of contents

Introduction

In this post, we will go over a few examples of how to create a jumping dots effect CSS animation.

This type of animation is usually used with loading animations before a page or HTML element (eg image) loads.

Steps to create a jumping dots animation in CSS:

  1. Create HTML structure the container for the dots.
  2. Style each element in the container to be circular dots
  3. Define our @keyframes for the jumping animation
  4. Apply the @keyframes animation to the dots

Example 1: Bouncing three dots animation

In this example, we will be creating 3 dots that will have a jumping animation like below:

The animation is simple if we break it down into a few steps.

1. Create HTML structure the container for the dots.

Firstly, creating our HTML is a simple as follows. The .dot class represents each of the dots.

<div class="container">
  <div class="dot"></div>
  <div class="dot"></div>
  <div class="dot"></div>
</div>

2. Style each element in the container to be circular dots

The next step to to style each of the dots with our CSS. We are using <div> tags to create dots with CSS, but I guess you can use SVGs or even an image if you prefer.

.dot {
  display: inline-block;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background-color: #4b9cdb;
}

The key properties are the width and height properties and the border-radius:50%. We need to set width and height because by default, div elements without any content will have a default width and height of 0x0.

The border radius setting just tells the browser to render our dots as circular. With out it, you will have square dots.

3. Define our @keyframes for the jumping animation

@keyframes jumpingAnimation {
  0 {
    transform: translate3d(0, 0,0);
  }
  50% {
    transform: translate3d(0, 15px,0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

4. Apply @keyframes animation to the dots

Lastly, we use the keyframe animation definition in step 3 to apply it to our dots like so:

.container .dot:nth-last-child(1) {
  animation: jumpingAnimation 0.6s 0.1s ease-in infinite;
}
.container .dot:nth-last-child(2) {
  animation: jumpingAnimation 0.6s 0.2s ease-in infinite;
}
.container .dot:nth-last-child(3) {
  animation: jumpingAnimation 0.6s 0.3s ease-in infinite;
}

Tip working with @keyframes

When working with @keyframes, a few things to keep in mind if you find your animation is not working as expected:

  • Cannot use the !important keyword - According to MDN “Declarations in a keyframe qualified with !important are ignored”
  • To avoid “janky” animations, prefer the use of 3d function such as translate3d() over just translate(). This offloads the calculations to the GPU and is not blocking the CPU operations. This gives a more smooth animation. You will not see it with these dots, but when you have a lot of elements on the page (or a less powerful device), this could help.

Example 2 - Jumping dots with “Typing” animation

In this example, we can modify our example 1 to have the effect of a “typing” animation. This is common in chat apps where this animation comes up when the other user is typing on their keyboard/ phone:

To get the above effect, we have the same HTML structure, but need to modify our @keyframe definition:

@keyframes jumpingAnimation {
  0 {
    transform: translate(0, 0);
  }
  16% {
    transform: translate(0, -15px);
  }
  33% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(0, 0);
  }
}

As you can see, we added a keyframe at the 16% mark - moving the dot up 15 pixels (-15px) and at the 33% keyframe, we want it to go back to zero.

This gives the effect of moving up and down quite quickly (eg of someone typing).

Example 3 - Loading dots animation

In this example, we extend the example 1 of bouncing animation and make it look like a loading bar animation with three dots:

We just need to extend the @keyframe with the following definition.

@keyframes expandAnimation {
  0 {
    height: 15px;
  }
  50% {
    height: 35px;
  }
  100% {
    height: 15px;
  }
}

Just need to expand the height of the dots to go from 15px to 35px and then back to 15px again!

Example 4 - falling dots loading animation

In this example, we are creating a falling loading animation. The three dots appear like they are falling disappearing - which gives a great loading animation:

Similar to the above examples, we need to define the following @keyframes. The idea here is to start the dot in a high Y position (-15px) and opacity zero.

Then for the 25, 50, 75 keyframes we move the dot to its original position (translate(0,0)) and make it appear with opacity:1

At the 100% keyframe we set it to disappear again (opacity:0) and going further down in the Y coordinate (translate(0,15px)). This just helps our animation not appear “janky” when we loop back.

@keyframes fallingAnimation {
  0% {
    transform: translate(0,-15px);
    opacity:0;
  }
  25%, 50%, 75% {
    transform: translate(0,0);
    opacity:1;
  }
  100% {
    transform: translate(0,15px);
    opacity:0;

  }
}

Tip: Create dots with box shadow

An alternative way to create these dots is using the box-shadow trick! Instead of having three HTML elements with the .dot class, we can just have one HTML <div> an use box-shadow!

box-shadow allow you to have a shadow effect for your HTML element and has the following syntax:

/* offset-x | offset-y | blur-radius | color */
box-shadow: 10px 5px 5px black;

Now the trick here is that we can define multiple box shadows by just adding a comma:

/* Any number of shadows, separated by commas */
box-shadow: 3px 3px red, -1em 0 0.4em olive;

So to create our dots, we just need to have one HTML and box-shadow with a comma separated list of shadows!

As an example, lets try to recreate example 2 with the dots typing effect. Our keyframe definition and CSS will look like below:

.dot-typing {
  position: relative;
  left: -9999px;
  width: 10px;
  height: 10px;
  border-radius: 5px;
  background-color: #9880ff;
  color: #9880ff;
  box-shadow: 9984px 0 0 0 #9880ff, 9999px 0 0 0 #9880ff, 10014px 0 0 0 #9880ff;
  animation: dot-typing 1.5s infinite linear;
}

@keyframes dot-typing {
  0% {
    box-shadow: 9984px 0 0 0 #9880ff, 9999px 0 0 0 #9880ff, 10014px 0 0 0 #9880ff;
  }
  16.667% {
    box-shadow: 9984px -10px 0 0 #9880ff, 9999px 0 0 0 #9880ff, 10014px 0 0 0 #9880ff;
  }
  33.333% {
    box-shadow: 9984px 0 0 0 #9880ff, 9999px 0 0 0 #9880ff, 10014px 0 0 0 #9880ff;
  }
  50% {
    box-shadow: 9984px 0 0 0 #9880ff, 9999px -10px 0 0 #9880ff, 10014px 0 0 0 #9880ff;
  }
  66.667% {
    box-shadow: 9984px 0 0 0 #9880ff, 9999px 0 0 0 #9880ff, 10014px 0 0 0 #9880ff;
  }
  83.333% {
    box-shadow: 9984px 0 0 0 #9880ff, 9999px 0 0 0 #9880ff, 10014px -10px 0 0 #9880ff;
  }
  100% {
    box-shadow: 9984px 0 0 0 #9880ff, 9999px 0 0 0 #9880ff, 10014px 0 0 0 #9880ff;
  }
}

Personally, I dont prefer this method since it is harder to read than our previous examples.

Browser Support

These animations should work with most modern browsers since they are only using @keyframes. If unsure we can add the vendor prefixes such as:

@-webkit-keyframes 
@-moz-keyframes
@keyframes

-o-box-shadow: 
-moz-box-shadow: 
-webkit-box-shadow

-webkit-transform
-moz-transform
-o-transform
-ms-transform

Summary

In this post, I went over examples of how to create a jumping dots animation. These animations are great for use in loading style animations in your web design.

An alternative to creating these dots is to use the box-shadow trick - having one HTML element and multiple shadows.

These animations are generally supported across modern browsers, but we can add vendor prefixes if not too sure!

👋 About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember 😅)

Follow along on Twitter , GitHub and YouTube