Creating simple CSS spinner-loader

How to do a Throbber without trouble

by Tibor Kopca Date: 05-04-2021 webdev css programming javascript

In today's article we will show you how to animate a basic loader that spins when some predefined action is defined, such as loading an image. That can be used on a website for example when there is a request running and the result is not yet retrieved.

What are they?

Loading animation, Loader, Spinner, Throbber, they go by many names, sometimes misleading because they do not always spin. Throbbers are actually the official name for them. Whatever they are called, they are supposed to do all the same - show an image in a program's interface which animates to show that the software is busy.


This means the system is performing an action in the background, launching an application, processing requests, downloading content, conducting intensive calculations or communicating with an external device. The user is thus able to see that he/she needs to wait until the process is finished.
Such a thing is many times needed also in text user interfaces, where there is no animation possible so its replaced by a fixed-width character which is cycled between “|”, “/”, “-” and “” forms in order to create an animation effect.

Spinner is something different than progress bar, because it doesn't show how much of the action has been completed. Unless there is for example added percentage numerics.
There are many iconic throbbers like Windows wait cursor in the form of hourglass and surely you recognize this typical throbber animation, as seen on many websites.


Using a CSS animation has an advantage that we are avoiding image request (.gif for example), that means the loader would be shown even if the system or transfer is slow or halted. That is how developers came to use pure CSS over GIF animations which were used a long time ago in web development.


Well enough of the theories, it's time to make our own simple throbber/spinner/loader.

Step by step

We would use to show the building process, a great tool where you can quickly try some pieces of code. Our spinner is going to be a simple circle spinning around its own centre.

First thing to do is create a single div element where the spinner would be shown. To target it in CSS it would have the class name “loader”.

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

Next we add CSS code:

.loader {
  width: 30px;
  height: 30px;
  border: 30px solid #f3f3f3;
  margin:10% auto;

As we can see in this picture, it's just a simple square with borders set to it.

Now we make it circular by adding border-radius:50% and we give color to the left border.


Now spin it!

At last, we add an animation to the loader class that makes the circle spin forever with a 0.8 second animation speed. In the property animation we need to write the name of the animation which will be defined in keyframes - in this case it's “spinIT”, time to complete animation in seconds, blend mode will be linear and it will be running continuously by the last attribute called infinite.
Additionally we decorate it with a bit of shadow.

Here is the complete code:

 .loader {
  width: 30px;
  height: 30px;
  border: 30px solid #f3f3f3;
  margin:5% auto;
  border-left: 30px solid #FF5D00;
  border-right: 30px solid #FF5D00;
  border-radius: 50%;
  animation: spinIT 0.8s linear infinite;
  filter: drop-shadow(0px 0px 8px gray)

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


For those browsers that do not support animation and transformation properties we should add this part of code.

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

Keep it simple

Now all of this above would only serve for designing the spinner, but for actually implementing it we need a content that its loading time is actually greater than a few milliseconds. This can be done by loading big pictures or files.
We used larger sized images, taken from - so called lorem ipsum of images. With this approach we can prevent also caching of the data so we can simulate better the loading time.

  <div class="image">
    <img src="">
<!--     <div class="loader"></div>    -->

Added CSS:

  border:solid black;

This is how it looks without a spinner.


Now we want to do that spinner in the place of image until it loads. We place the spinner inside the container with the image and set it center with CSS.

  <div class="image">
<img src="">
<div class="loader"></div>   


  border:solid black;

Now we prepare the rest of the code, by adding id=”img” to the element img, because what we are going to do is to have an image container not displayed until it's loaded into memory.

<img src="" id="img" class="hidden animated">

In CSS file it would be as follows:
  animation: animate 3s;
@keyframes animate{
  from{opacity:0 }
  to{opacity:1 }

Now  we are set to JavaScript in the next section.

JavaScript the s..t out of it!

For the JS, we add a simple event listener to hide the loader when the image is completely loaded.
The last part is to add code so we access the elements we're going to manipulate.
First we add an event listener to the window, which would start the autoexecutable function on load of the content.

Make no mistake, an external js file or <script> should be placed behind all the HTML code so the text content would be loaded first - in this time is the spinner visible. Once JS code is loaded, it will run the code inside the eventlistener.

window.addEventListener("load", function(){
document.getElementById("loaderSpinner").style.display = "none";
document.getElementById("img").style.display = "block";

In the second row we can see how to stop the loader, once the image itself would load.
And we remove class “hidden” from the image, so it would be visible.

See the Pen Loader_spinner by Tibor (@TiborKopca) on CodePen.

Complete code to be seen here:

Loading images with the Fetch API

When it comes to JavaScript integration, we can showcase it on the Fetch API of one of our coworkers, Iveta Karailievova, check out her articles here>, she wrote recently how to use it.

This API basically obtains resources, in this case an image from the URL.

We altered the code a bit to implement timeout to the event listener, this allows us to postpone the time of the function execution so we can enjoy the spinner better.

The forked code can be seen here >


There are many ways to go when you are about to make a custom spinner, for example using CSS pseudoelements. We showed you the basic one, but depends only on your imagination how you make it at the end. Here are some possibilities for inspiration to see what can be done.

Hope we showed you how it can be quite easily created some custom CSS throbble for your website to be even more attractive for everybody.

Image by Tibor Kopca.


by Tibor Kopca Date: 05-04-2021 webdev css programming javascript hits : 1811  
Tibor Kopca

Tibor Kopca

From tinkering with computers as a teenager, through a career in datacenter he stepped into web development with full force and started coding. Absorbs all information like a sponge.
Fan of aerospace, engineering, information technologies and watches.


Related Posts

Nesting: future proofing CSS

Although not currently supported by browsers, there is a proposal for CSS nesting to support a feature that would provide better readability to native CSS, so in the future it…

How to Send Email from an HTML Contact Form

In today’s article we will write about how to make a working form that upon hitting that submit button will be functional and send the email (to you as a…

Use the SRCSET attribute to improve your SEO

There is a new standard HTML attribute that can be used in conjunction with IMG called SRCSET. It is new and important as it allows webmasters to display different images…

How to multiply matrices in JavaScript

It may seem strange to want to know how to multiply matrices in JavaScript. But we will see some examples where it is useful to know how to perform this…

JavaScript Formatting Date Tips

Something that seems simple as the treatment of dates can become complex if we don't take into account how to treat them when presenting them to the user. That is…

Starting with Bootstrap-Vue step by step

Today we will show you how to use BootstrapVue, describe the installation process and show basic functionality. The project’s based on the world's most popular CSS framework - Bootstrap, for building…

Bootstrap 5 beta2. What offers?

Since the release of the Bootstrap 4 is three years, in this article we will present what is new in the world’s most popular framework for building responsive, mobile-first sites.…

Validating HTML forms using BULMA and vanilla JavaScript

Today we are going to write about contact forms and how to validate them using JavaScript. The contact form seems to be one of the top features of every basic home…

How to use Parallax.js effect on your website

Today, we're going to write about the parallax effect, similar to parallax scrolling, and how to implement it to improve your landing page. In webdev, they say mobile first -…

Django vs. Laravel: Market Share Comparison

There are two leading frameworks in the web development segment: Django and Laravel. In this article, we prepared a Django and Laravel comparison focusing on their market share so that…

How to make the website's dark mode persistent with Local Storage, CSS and JS

Recently we wrote about how to do a switchable alternative color mode or theme, a very useful and popular feature to websites. Today’s article is going to be about how…

A Java approach: While loop

Hello everyone and welcome back! After having made a short, but full-bodied, introduction about cycles, today we are finally going to see the first implementations that use what we have called…

We use our own and third-party cookies to improve our services, compile statistical information and analyze your browsing habits. This allows us to personalize the content we offer and to show you advertisements related to your preferences. By clicking "Accept all" you agree to the storage of cookies on your device to improve website navigation, analyse traffic and assist our marketing activities. You can also select "System Cookies Only" to accept only the cookies required for the website to function, or you can select the cookies you wish to activate by clicking on "settings".

Accept All Only sistem cookies Configuration