Create a Bouncing Loader Animation with Tailwind CSS

Davis Gitonga

Davis Gitonga / July 12, 2021

5 min read

Create a Bouncing Loader Animation with Tailwind CSS

Photo by Jessica Knowlden


According to the official documentation, Tailwind CSS is a utility-first CSS framework for rapidly building custom user interfaces. I like to think of it as a way to write inline styling and achieve a beautiful interface without writing a single line of CSS.

What You'll Learn

In this article, we're going to build a bouncing loader using CSS3 animation keyframes. We'll do all of this with Tailwind CSS utility classes.


You should be familiar with:

You'll need to have Node and NPM installed on your computer. Use node -v on the command line to find your local Node version.


Here’s a sneak peek of what you will be developing by the end of this tutorial:

Or click the following Tailwind Play link to see a working example:

Writing the Markup

<div class="flex justify-center">
  <span class="circle animate-loader"></span>
  <span class="circle animate-loader animation-delay-200"></span>
  <span class="circle animate-loader animation-delay-400"></span>

We added a div with the classes flex & justify-center, which places the bouncing page loader in the middle of the page horizontally using Flexbox. Inside this div, we add three consecutive span elements each representing a page loader circle.

Setting up Tailwind CSS

Tailwind CSS requires Node.js 12.13.0 or higher.

Install Tailwind via npm

Install Tailwind and its peer-dependencies using npm:

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

Create your configuration files

Next, generate your tailwind.config.js and postcss.config.js files:

npx tailwindcss init -p

This creates a postcss.config.js file that includes tailwindcss and autoprefixer already configured:

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {}

Customizing your Tailwind installation

It also creates a minimal tailwind.config.js file at the root of your project, where you can define any customizations.

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {
      animation: {
        loader: 'loader 0.6s infinite alternate'
      keyframes: {
        loader: {
          to: {
            opacity: 0.1,
            transform: 'translate3d(0, -1rem, 0)'
  variants: {
    extend: {}
  plugins: []

In our tailwind.config.js file, we extend both the animation and keyframes objects to include our custom animation.

Keyframes is used to define the animation behavior and give us complete control of one cycle of a CSS animation.

The keyframes object defines an animation with two states, where the element changes opacity and is repositioned in 3D space using transform: translate3d(). Using a single axis translation on transform: translate3d() improves the performance of the animation.

You then reference these keyframes by name in the animation section of your theme configuration: You style the element you want to animate with the animation property and its sub-properties. Using this property, you can control the timing, duration, and other details of your animation.

Here you have used the following animation sub-properties:

animation: animation-name, animation-duration, animation-iteration-count,
  • animation-name: Defines the name of your animation which is loader in my case.
  • animation-duration: Configures the length of time which your animation will take to complete one cycle.
  • animation-iteration-count: Tells how many times you want your animation cycle to play before it stops.
  • animation-direction: Defines which direction your animation is going to play.

Apart from these, there are several other sub-properties as well. You can browse through them in the Mozilla Web Docs.

Based on these, you have defined the animation as follows:

animation: loader 0.6s infinite alternate;

This line of code does the following four things:

  • Tells the span elements to use our keyframe loader.
  • Sets the length of the animation to 0.6 seconds.
  • Runs the animation an infinite number of times.
  • Upon completion of one single cycle, the animation direction alternates, i.e., it reverses.

Next, include Tailwind in your CSS.

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer utilities {
  .animation-delay-200 {
    animation-delay: 0.2s;
  .animation-delay-400 {
    animation-delay: 0.4s;

.circle {
  @apply w-4 h-4 my-12 mx-1 bg-gray-500 rounded-full;

Tailwind will swap the @tailwind directives out at build-time and inject Tailwind's base styles based on your configured design system.

The easiest way to add your custom utilities to Tailwind is by using the @layer directive. We use that to create animation-delay utilities.

animation-delay is used on the second and third span respectively, so that each element does not start the animation at the same time.

We also use the @apply directive to inline any existing utility classes into our CSS. The spans are given width and height of 1rem w-4 h-4, and a class rounded-full to turn them from squares to circles.

my-12 mx-1 specifies that each circle has a top/bottom margin of 3rem and left/right margin of 0.25rem so that they do not directly touch each other, giving them some breathing room.


This animation shows how powerful CSS animations are and how to integrate them in your tailwind CSS project.

Thanks for reading! If this tutorial was helpful, try it out yourself and share your feedback in the comments section below.

Happy Coding!🤓

share your thoughts