My WebDev Notes: CSS loaders
Tags: html, css
Published: 2020-02-25 12:12:14

---
title: My WebDev Notes: CSS loaders
published: true
description: A detailed experiment on how to create loaders in CSS
tags: html, css
series: My WebDev Notes
---

> <b>Check the CSS loader online: https://ziizium.github.io/my-webdev-notes/css-loaders/ or https://4q0sb.csb.app/</b>

A loader is an animation that indicates an application or process is busy performing an operation. You can find a loader in an application or a web page as a circle rotating infinitely until the application responds or completes the process it was working on.

In this experiment, I tried to create a simple loader using HTML and CSS. I will show you how I did it, some issues I ran into, and the fix. I hope you learn something from it.

I have discussed some of the ingredients necessary for the loader to work in the series [FrontEnd Development: Zero to hero](https://dev.to/ziizium/frontend-development-zero-to-hero-j0j) specifically:

* [CSS Animations and Transitions](https://dev.to/ziizium/css-animations-and-transitions-51j8)

Let's dive in.
 
<hr>

The loader that we'll create will be a simple one. The loader will be a single `div` element with some CSS applied to it.

The `div` element will be inside a `main` element alongside an `h1` element, these are just cosmetics to make the loader stand out on the web page.

Here is the HTML:

```html
<main>
  <h1>CSS Loaders</h1>
  <div class="loader"></div>
</main>
```

The CSS is the main stuff therefore, we'll dissect it together.

We'll like to set up the environment for our loader. We begin by giving the `main` tag some background color, width, and internal spacing (padding). The `h1`is also aligned to the center of the page.

When you take a look at the CSS code for the `main` tag, you'll notice the following line:

```css
margin: 0 auto;
```

When we talked about CSS margins, I mentioned that the `margin` property is actually a shortcut for four other properties namely:

* `margin-top`
* `margin-right`
* `margin-bottom`
* `margin-left`

The `margin` property when used with just 2 properties, the first property will represent the _top and bottom_ and the second property will represent the _right and left_.

We used `0` for the _top and bottom_ and `auto` for the _right and left_. The `auto` keyword here is an instruction to the browser to apply equal margins on both sides of `main` hence, it will always appear at the center of the viewport (available browser window).

Another thing to note is the calculation for the width:

* `50 * 16 = 800px`; This assumes the default browser font size of `16px`

Here is the CSS for `main` and the subsequent `h1` tag:

```css
main {
    width: 50em;             /* 50 * 16 = 800px.*/
    margin: 0 auto;          /* Take it to the center of the page */
    background-color: #ccc;  /* Silver */
    padding: 1.5em;          /* Internal spacing */ 
    display: block;          /* For Internet Explorer */
}

/* We make use of descendant selectors. Just for FUN */
main > h1 {
    text-align: center;       /* You get this right? */
}
```

It's time for the real deal. When you take a look at a loader, the surroundings of the loader and the _ring_ that rotates infinitely are CSS borders.

The _ring_ is a `border-top` top property. And I am pretty sure you know most loaders are _round_ in shape. The `border-radius` property with a value of `50%` is responsible for this.

So here we go:

```css
.loader {
    border: 16px solid #f3f3f3;     /*  Light gray */
    border-top: 16px solid #48d1cc; /*  The border top will be the color of the spinner */
    border-radius: 50%;             /*  Make it round */
}
```

Save and refresh your browser and take note of the changes.

![CSS loaders at its inception](https://dev-to-uploads.s3.amazonaws.com/i/p4qg6zgzr9oelujlhcwr.png)<figcaption>CSS loader at its early stages</figcaption>

That looks good since we are progressing but it is not appealing. The `div` is an empty element, we will need to give it a `height` and `width` to see the full effect of the `border-radius` and `border-top` property.

```css
.loader {
    /* All properties remain the same */
    
    width: 120px;             /*  The width of the loader */
    height: 120px;            /*  The height is necessary since the div has no content */
}
```

Save and refresh your browser.

![CSS loader coming together](https://dev-to-uploads.s3.amazonaws.com/i/3e7vsp4lftoo4bmmbmi2.png)<figcaption>CSS loader coming together</figcaption>

What's left? Some spinners! But wait how will a border spin? _CSS Animations_ and _CSS Transforms!_.

With CSS animations you can move page element around (`border-top`). CSS transform will allow the spinner to move around in a circle.

The `transform` property applies a 2D or 3D transformation to an element. This property allows you to rotate, scale, move, skew, etc., elements. ([source](https://www.w3schools.com/cssref/css3_pr_transform.asp)).

Specifying a value other than `none` for the `transform` property establishes a new local coordinate system at the element that it is applied to. ([source](https://www.w3.org/TR/css-transforms-1/#transform-rendering)).

Using the `animation` property we can specify how the animation behaves. The `animation` property is a shorthand for other animation properties and it has large browser support based on [Can I use](https://caniuse.com/#search=CSS%20animation).

![CSS Animation data from Can I use](https://dev-to-uploads.s3.amazonaws.com/i/lydn18duo62rjjhqyrwi.png)<figcaption>CSS Animation data from Can I use</figcaption>

The property that will make the spinner spin endlessly is the `animation-iteration-count` with the value of `infinite`.

In the subsequent code, the `animation-iteration-count` is part of the `animation` shorthand property and it's the fourth property in the value.

Please read the comments.

```css
.loader {
     /* All properties remain the same */

     /**
       * 1. animation-name
       * 2. animation-duration
       * 3. animation-timing-function
       * 4. animation-iteration-count
       *
       * If you would like to target webkit specific browsers
       * change animation to -webkit-animation
       */
	            /*1*/ /*2*/  /*3*/   /*4*/
	animation: spinner 2s    linear  infinite;
}
```

Save and refresh your browser you'll realize the animation is not active because we are missing one final ingredient, _keyframes_.

Keyframes specify the animation code. Where it begins and where it will stop.

We need the spinner to rotate in circles, therefore, we'll use the `rotate` value for the `transform` property starting at `0%` and ending at `360%`.

```css
/**
  * If you would like to target WebKit specific browsers
  * change keyframes to -webkit-keyframes
  */

@keyframes spinner {
    0% {
	transform: rotate(0deg);   /* Start from 0 degrees  */
    }
    100% {
	transform: rotate(360deg); /* End at 100 degrees  */
    }
}
```

And that's it. Save and refresh your browser to see the changes.

Check out the sandbox below:

{% codesandbox css-loaders-4q0sb %}

And the Github repo:

{% github  ziizium/my-webdev-notes %}

_We can do better by creating multiple loaders, I might not write about it but you can check the Github repo anytime and if I do write about it, I will update this article._

_Have fun!_.