How to Create Loading Animation With HTML & CSS
How to Create Loading Animation With HTML & CSS

In this video you will learn how to build 3 most popular loading animations using only css and html.
Let's jump right into it.

The point of this video is not only to show you how to make 3 popular spinners but you teach you concepts how they are done so that you can implement them by yourself.


Let's look on the first example. This is a typical round loader where a quarter of it is in other color and rotates.

So first we need to make element where we will apply our css

<div class="loader1"></div>

Now we need to make it of certain size and round. For this we can use border-radius:50%;

.loader1 {
  border-radius: 50%;
  width: 120px;
  height: 120px;
  border: 16px solid #f3f3f3;
}

As you can see I also used a thick border this actually look like finished element. Now we just need to make 1 border of the other color. As we have a circle because of border radius it will work out of the box.

.loader1 {
  border: 16px solid #f3f3f3;
  border-top: 16px solid #3498db;
  border-radius: 50%;
  width: 120px;
  height: 120px;
}

As you can see our loading already looks like we planned. Now we just need to rotate the whole element. For this we can use keyframes. They allow to create a custom animation.

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

So here we created a custom animation spin where we specify how to should change from 0% to 100%. And we are setting rotate here. Now we only need to use our animation.

.loader1 {
  border: 16px solid #f3f3f3;
  border-top: 16px solid #3498db;
  border-radius: 50%;
  width: 120px;
  height: 120px;
  animation: spin 2s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

As you can see it works exactly as expected. You can also change the speed or the width of borders that can change the look completely.

.loader1 {
  border: 5px solid red;
  border-top: 5px solid green;
  border-radius: 50%;
  width: 120px;
  height: 120px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

Second animation is completely different but based on the same principles. We have 4 block or lines which are going in and out. Let's write markup first.

<div class="loader2">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
<div>

Now let's render the lines

.loader2 {
}

.loader2 span {
    display: inline-block;
    width: 5px;
    height: 20px;
    background-color: #3498db;
}

We don't need any styles on container and we just set 4 lines inline. Again you can change color, thickness or size as you wish.

Now we need to create an animation that will increase and decrease height of the element. We can use transform and scale the element by y.

@keyframes grow{
  0%, 100%{
    transform: scaleY(1);
  }

  50%{
    transform: scaleY(1.8);
  }
}

The most important here that on 0% and 100% we are on scale 1. So on initial size. On 50% we scale the element to 1.8.
Let's use the animation now.

.loader2 span:nth-child(1){
  animation: grow 1s infinite;
}

As you can see it works. So let's apply it to all elements.

.loader2 span:nth-child(1){
  animation: grow 1s infinite;
}

.loader2 span:nth-child(2){
  animation: grow 1s infinite;
}

.loader2 span:nth-child(3){
  animation: grow 1s infinite;
}

.loader2 span:nth-child(4){
  animation: grow 1s infinite;
}

It looks okay but kind of boring because the all grows together. We can make it more interesting by setting ease-in-out attribute to animation with different delays.

.loader2 span:nth-child(1){
  animation: grow 1s ease-in-out infinite;
}

.loader2 span:nth-child(2){
  animation: grow 1s ease-in-out 0.15s infinite;
}

.loader2 span:nth-child(3){
  animation: grow 1s ease-in-out 0.30s infinite;
}

.loader2 span:nth-child(4){
  animation: grow 1s ease-in-out 0.45s infinite;
}

Now it is look more realistic and interesting.


The third animation is 3 bubbles which are changing the size and transparency. Let's add a markup first.

<div class="loader3">
  <span></span>
  <span></span>
  <span></span>
</div>

Now let's position elements and style them.

.loader3 {
  width: 120px;
  justify-content: space-between;
  display: flex;
  align-items: center;
}

.loader3 span {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: #3ff9dc;
}

As you can see we rendered 3 bubble with correct colors and positions. Now the only thing that left is animation. This pulsing is scaling of the element and changing opacity.

@keyframes pulse {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: .25;
    transform: scale(.75);
  }
}

Now we can apply pulse with different delay to make it pretty.

.loader3 span:nth-child(1){
  animation: pulse .4s ease 0s infinite alternate;
}

.loader3 span:nth-child(2){
  animation: pulse .4s ease .2s infinite alternate;
}

.loader3 span:nth-child(3){
  animation: pulse .4s ease .4s infinite alternate;
}

As you can see it look exactly like we intended.

As you can see it's not that difficult to create your own loaders. It's mostly styled elements with custom animation on keyframes. You might of course ask why not just use animated image. Plain css with html is more configurable, resizable and reusable. And if we are talking about frontend frameworks we can easy hide all this markup with css inside component.

Also if you want to improve your programming skill I have lots of full courses regarding different web technologies.

📚 Source code of what we've done