BlogHome
Create Loading Animations with SVG and CSS

Create Loading Animations with SVG and CSS

Jan 29, 2021Updated on Feb 6, 2022

One of the best ways to go about creating loading animations for your web projects that doesn't involve loading assets from your web server, external CDN's or third party Javascript plugins is creating it within your web app using the same web technologies you use to render them. This ensures that your animations appear just as soon as you need them making sure the user experience isn't affected based on the speed of a user's connection.

In this tutorial we are going to make a simple loading animation for web projects using HTML and CSS.

The end result we are after is the following animation. Loading Animation

Add the following html template:

<div class="svg-loader">
  <svg class="svg-container" height="100" width="100" viewBox="0 0 100 100">
    <circle class="loader-svg bg" cx="50" cy="50" r="45"></circle>
    <circle class="loader-svg animate" cx="50" cy="50" r="45"></circle>
  </svg>
</div>

As evident from the illustration above the animation template consists of two circles one on top of another, with the first circle being thicker than the second one both having the same circumference giving the illusion of one circle being inside the other.

The cx and cy attributes inside the circles are the x-axis and y-axis coordinates respectively of the two circles. They make sure that the two circles are centered on the same coordinate.

Add the following css:

.svg-loader{
  display:flex;
  position: relative;
  align-content: space-around;
  justify-content: center;
}
.loader-svg{
  position: absolute;
  left: 0; right: 0; top: 0; bottom: 0;
  fill: none;
  stroke-width: 5px;
  stroke-linecap: round;
  stroke: rgb(64, 0, 148);
}
.loader-svg.bg{
  stroke-width: 8px;
  stroke: rgb(207, 205, 245);
}

The above css makes sure the loading component is centered within it's container also making sure there are different stroke widths and colors for the two circles.

We then animate the second circle, which will be on top of the first circle with CSS to complete our loading animation:

.animate{
  stroke-dasharray: 242.6;
  animation: fill-animation 1s cubic-bezier(1,1,1,1) 0s infinite;
}

@keyframes fill-animation{
  0%{
    stroke-dasharray: 40 242.6;
    stroke-dashoffset: 0;
  }
  50%{
    stroke-dasharray: 141.3;
    stroke-dashoffset: 141.3;
  }
  100%{
    stroke-dasharray: 40 242.6;
    stroke-dashoffset: 282.6;
  }
}

Here's what's going on in the above css. When we draw our circle it is simply a single dash stroke painting the outline of our shape from beginning to the end of the circle, the stroke-dasharray attribute gives us the ability to break that into a pattern of dashes and gaps. We can exploit this feature to obtain the animation end result that we want.

In order to have a smooth animation effect like the one above we need to know the circumference of the circle, where circumference = 2 x pi x radius. We then use the stroke-dasharray attribute to draw a maximum of one dash and gap alternating their sizes at different states of the animation while maintaining the circumference length when the two are added.

With a circle radius of 45 we get the circumference of 282.6, so when we set the stroke-dasharray value to 141.3 it means that the dash and gap have that same value which add to give a sum of 282.6.

The stroke-dashoffset attribute is a presentation attribute defining an offset on the rendering of the associated dash array, this offset gives the rotational effect to the loading animation, otherwise the animation will appear broken. This is all that is happening in the fill-animation animation. We finish by applying this animation to the second circle with the .animation class making sure that this animation goes on infinitely.

This is just a base to the sort of animations one can make with SVG and CSS, get experimental and creative creating fast and pixel perfect loading animations for your web projects.