I built these 5 types of loading animation in HTML and CSS, which do you prefer?

Adeyele Paul - Apr 22 - - Dev Community

As a lover of clean UI design and smooth animations, I've always been fascinated by the creative possibilities of the humble loading state. From minimal spinners to energetic shape-shifters, the permutations are endless.

So I recently challenged myself to explore different loading styles and see how many unique yet practical animations I could craft with just HTML and CSS.

After lots of coding,inspiration, doodling, and chromatic experimentation, I landed on this collection of 5 distinctive loading animations to share.

Want to see the 5 cool ones I came up with?

Let's go.

Animation 1: The Minimalist Spinner

Sometimes less is more when it comes to loading animations. This first style keeps things clean and simple with a minimalist spinning line.

Code:

HTML:



<div class="loader">
  <div class="line"></div>
</div>


Enter fullscreen mode Exit fullscreen mode

CSS:



.loader {
  width: 40px;
  height: 40px;
  margin: 0 auto;
  border: 3px solid #FF9900;
  border-radius: 50%;
  border-top-color: transparent;
  animation: rotate 1s infinite linear;
}

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


Enter fullscreen mode Exit fullscreen mode

This uses a div element with a border to create the circle outline, and border-top-color: transparent to leave a gap for the spinning line effect. The animation rotates it 360 degrees for a smooth endless spin.

Result:

Image description

Use Cases:
This simple spinner works well in minimal UI designs or tight spacing contexts where you don't want the loading state to be too obtrusive. Its subtle rotation conveys just enough activity without being distracting.

Animation 2: The Bouncing Ball

This next loading animation is fun and bouncy! It creates an infinite loop of a ball bouncing up and down, injecting some delightful movement into an otherwise dull loading period.

Code:

HTML:



<div class="loader">
  <div class="ball"></div>
</div>


Enter fullscreen mode Exit fullscreen mode

CSS:



.loader {
  width: 70px;
  height: 120px;
  margin: 0 auto;
  position: relative;
}

.ball {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: linear-gradient(135deg, #255426, #8bba8c);
  position: absolute;
  bottom: 0;
  left: 10px;
  animation: bounce 0.6s ease-in-out infinite alternate;
}

@keyframes bounce {
  0% { transform: translateY(0); }
  100% { transform: translateY(-70px); }
}


Enter fullscreen mode Exit fullscreen mode

Here I used CSS positioning to place the ball at the bottom initially, and the animation makes it translate (move) vertically between 0 and -70px to create the bounce effect.

Result:

Image description

Use Cases:
I think since the bouncing ball loading injects some fun, playful movement that catches the eye - It works well for communicating a lengthier loading process where you want to keep users engaged and interested. That looping bounce just provides that constant reassurance that data is still loading.

Animation 3: The Morphing Blob

This one was quite hard but I pull through. It has that wonderfully organic, amorphous feel to it. A shapeshifting blob seamlessly transitions between different forms in an endless loop.

Code:

HTML:



<div class="loader">
  <div class="blob"></div>
</div>


Enter fullscreen mode Exit fullscreen mode

CSS:



.loader {
  width: 100px;
  height: 100px;
  position: relative;
}

.blob {
  width: 50px;
  height: 50px;
  background: linear-gradient(135deg, #8EC5FC, #E0C3FC);
  border-radius: 50%;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 20px rgba(142, 197, 252, 0.5);
  animation: morph 5s linear infinite;
}

@keyframes morph {
  0%, 100% {
    border-radius: 50%;
    transform: translate(-50%, -50%) scale(1);
  }

  33% {
    border-radius: 30% 70% 70% 30% / 30% 29% 71% 70%;
    transform: translate(-50%, -50%) rotate(90deg) scale(1.2); 
  }

  66% {
    border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
    transform: translate(-50%, -50%) rotate(180deg) scale(0.8);
  }
}


Enter fullscreen mode Exit fullscreen mode

The magic is in the @keyframes animation, where I changed the border-radius and apply different transform values to warp the blob's shape over time. The background gradient and box-shadow create a soft, glowing effect.

Result:

Image description

Use Cases:
Use it for situations where you want to convey an active "shape-changing" state, like applying image filters, updating data visualizations, or maybe processing graphic-intensive tasks.

Animation 4: The Pulsing Dots

This loader keeps things simple yet visually engaging with a few pulsing dots creating a rippling, wave-like effect.

The Code:

HTML:



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


Enter fullscreen mode Exit fullscreen mode

CSS:



.loader {
  width: 100px;
  height: 20px;
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #ABB2B9;
  animation: pulse 1.5s infinite ease-in-out;
}

.dot:nth-child(1) {
  animation-delay: 0s;
  background: #EF476F;
}

.dot:nth-child(2) {
  animation-delay: 0.5s; 
  background: #FFD166;
}

.dot:nth-child(3) {
  animation-delay: 1s;
  background: #06D6A0;
}

@keyframes pulse {
  0%, 100% {
    transform: scale(0.6);
    opacity: 0.5;
  }
  50% {
    transform: scale(1);
    opacity: 1;
  }
}


Enter fullscreen mode Exit fullscreen mode

It's when I coded the pulse animation with the staggered delays, that the magic actually happened. Each dot scaled up and down at different times, creating this cascading pulsing sequence. Varying the dot colors adds extra visual flair.

Result:

Image description

Use Cases:
This one can work well when you need something simple that provides subtle visual feedback during shorter loading scenarios. Its clean, minimalist pattern won't overwhelm or distract, but still signals that content is loading. Use it for quick load transitions like pulling data from an API or partial page renders.

Animation 5: The Filling Rotating Square

This loader has an incredibly satisfying fill-up motion that builds anticipation as the square gets closer and closer to completion. I got this design inspiration from a YouTube short and I decided to make my own in what is called steal like an artist.

Code:

HTML:



<div class="loader">
  <div class="fill-box"></div>
</div>


Enter fullscreen mode Exit fullscreen mode

CSS:



.loader {
  width: 50px;
  height: 50px;
  border: 2px solid #333;
  position: relative;
}

.fill-box {
  width: 100%;
  height: 100%;
  transform: rotate(0);
  background: conic-gradient(#39CCCC, #AA66CC, #39CCCC);
  animation: filling 1s infinite linear;
}

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


Enter fullscreen mode Exit fullscreen mode

The square outline is created with a div border, while the inner .fill-box uses a rotating conic gradient background to produce the filling animation effect.

Result:

Image description

Use Cases:
The square fill loader is bright, bold, and direct - it commands your attention which makes it fit for loading periods where you really want that in-your-face "Watch me load!" experience, like launching an app or game, uploading large files, or processing intensive tasks.

Wrap up

And that's a wrap on all 5 loading animation demos! We covered a range of styles from cool and minimal, to vibrant and playful.

But now I want to know - which one was your favorite? Was it the minimalistic? The cute lil bouncy ball? That shapeshifting, amorphous blob? The simple pulsing dot pattern? Or did that vivid, filling rotating square just scratch your loading animation itch perfectly?

Let me know your top pick in the comments! And of course, feel free to grab any of the code snippets and build your own remixed versions.

. . . . . . . . .