How to Create Loading Spinner With CSS

Earlier, many web developers were using animated loading spinner .gifs. But CSS animations allow us to easily create a loading spinner.

We are going to show how to create a simple circle spinning around its center.

Create HTML

  • Create a <div> with a class name "spin" in the body section.
<body>
  <div class="spin"></div>
</body>

Add CSS

  • Create a circle setting the width and the height of it.
  • Set the border-radius to 50% to make it rounded.
  • Give color to the border.
  • Give color to the spinner with the border-bottom-color property.
  • Specify the animation, which has four values. The first value is the animation-duration which is 1.5s, meaning the length of time that animation takes to complete one cycle. The second value is the animation-timing-function which is set to linear meaning the animation has the same speed throughout the animation. We set the animation-iteration-count to infinite so that the animation plays endlessly. The final value is the animation-name.
  • Set the position to "absolute" so as to position the element relative to its closest positioned ancestor.
  • Specify the top and left positions of the spinner.
  • Define the transform translate3d, which is a 3D transform function used to move an element in 3D space. It translates the element by a vector [tx, ty, tz]: tx is the translation along the x-axis, ty is the translation along the y-axis, and tz is the translation along the z-axis. And define the rotate() function used to rotate an element in the 2D space.
.spin::before {
  animation: 1.5s linear infinite spinner;
  animation-play-state: inherit;
  border: solid 5px #cfd0d1;
  border-bottom-color: #1c87c9;
  border-radius: 50%;
  content: "";
  height: 40px;
  position: absolute;
  top: 10%;
  left: 10%;
  transform: translate3d(-50%, -50%, 0);
  width: 40px;
  will-change: transform;
}

Here’s the final result of our code.

Example of creating a loading spinner:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      @keyframes spinner {
        0% {
          transform: translate3d(-50%, -50%, 0) rotate(0deg);
        }
        100% {
          transform: translate3d(-50%, -50%, 0) rotate(360deg);
        }
      }
      .spin::before {
        animation: 1.5s linear infinite spinner;
        animation-play-state: inherit;
        border: solid 5px #cfd0d1;
        border-bottom-color: #1c87c9;
        border-radius: 50%;
        content: "";
        height: 40px;
        width: 40px;
        position: absolute;
        top: 10%;
        left: 10%;
        transform: translate3d(-50%, -50%, 0);
        will-change: transform;
      }
    </style>
  </head>
  <body>
    <div class="spin"></div>
  </body>
</html>

Result

Example of creating a loading spinner with the "ease-in-out" value:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      body {
        margin-top: 100px;
        background-color: #0042A4;
        color: #fff;
        text-align: center;
      }
      h1 {
        font: 1.5em 'Roboto', sans-serif;
        margin-bottom: 30px;
      }
      .spin {
        display: inline-block;
        width: 50px;
        height: 50px;
        border: 3px solid rgba(255, 255, 255, .3);
        border-radius: 50%;
        border-top-color: #fff;
        animation: spin 1s ease-in-out infinite;
        -webkit-animation: spin 1s ease-in-out infinite;
      }
      @keyframes spin {
        to {
          -webkit-transform: rotate(360deg);
        }
      }
      @-webkit-keyframes spin {
        to {
          -webkit-transform: rotate(360deg);
        }
      }
    </style>
  </head>
  <body>
    <h1>Loading Spinner</h1>
    <div class="spin"></div>
  </body>
</html>

Example of creating a loading spinner with the "linear" value:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .spin {
        border: 16px solid #0042A4;
        border-radius: 50%;
        border-top: 16px solid #3775CF;
        border-right: 16px solid #619BEE;
        border-bottom: 16px solid #96BFF9;
        border-left: 16px solid #C9E0FF;
        width: 50px;
        height: 50px;
        -webkit-animation: spin 1.5s linear infinite;
        animation: spin 1.5s linear infinite;
      }
      @-webkit-keyframes spin {
        0% {
          -webkit-transform: rotate(0deg);
        }
        100% {
          -webkit-transform: rotate(360deg);
        }
      }
      @keyframes spin {
        0% {
          transform: rotate(0deg);
        }
        100% {
          transform: rotate(360deg);
        }
      }
    </style>
  </head>
  <body>
    <div class="spin"></div>
  </body>
</html>

Example of creating a loading spinner with the "cubic-bezier" value:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      body,
      html {
        background: #002F74;
      }
      .spin-container {
        text-align: center;
        margin-top: 100px;
      }
      .spin {
        border: 3px solid #0D4B9F;
        width: 200px;
        height: 200px;
        margin: 0 auto;
        border-radius: 50%;
        border-left-color: transparent;
        border-right-color: transparent;
        animation: rotate 2s cubic-bezier(0.26, 1.36, 0.74, -0.29) infinite;
      }
      #loader2 {
        border: 3px solid #E0EDFF;
        width: 220px;
        height: 220px;
        position: relative;
        top: -216px;
        border-left-color: transparent;
        border-right-color: transparent;
        animation: rotate2 2s cubic-bezier(0.26, 1.36, 0.74, -0.29) infinite;
      }
      #loader3 {
        border: 3px solid #005CDC;
        width: 240px;
        height: 240px;
        position: relative;
        top: -452px;
        border-left-color: transparent;
        border-right-color: transparent;
        animation: rotate 2s cubic-bezier(0.26, 1.36, 0.74, -0.29) infinite;
      }
      #loader4 {
        border: 3px solid #94B6E5;
        width: 260px;
        height: 260px;
        position: relative;
        top: -708px;
        border-left-color: transparent;
        border-right-color: transparent;
        animation: rotate2 2s cubic-bezier(0.26, 1.36, 0.74, -0.29) infinite;
      }
      @keyframes rotate {
        0% {
          transform: rotateZ(-360deg)
        }
        100% {
          transform: rotateZ(0deg)
        }
      }
      @keyframes rotate2 {
        0% {
          transform: rotateZ(360deg)
        }
        100% {
          transform: rotateZ(0deg)
        }
      }
      #text {
        color: #D6E3F6;
        font-family: Arial;
        font-size: 15px;
        position: relative;
        top: -857px;
      }
    </style>
  </head>
  <body>
    <div class="spin-container">
      <div class="spin" id="loader"></div>
      <div class="spin" id="loader2"></div>
      <div class="spin" id="loader3"></div>
      <div class="spin" id="loader4"></div>
      <span id="text">LOADING...</span>
    </div>
  </body>
</html>