Create Animated Loaders and Spinners with CSS3

Loaders and spinners are a common sight in webpages, popping up whenever the server loads a page. For long, animated gifs have served the purpose. However, a plethora of custom made, editable CSS spinners are now available. This tutorial will walk you through the creation of basic animated loaders and how to apply elementary mathematics for various transformations, rather than a hit and trial approach.

Rotatory Loaders:

These are the most common spinners used in most of the websites as well as loading screens of various offline applications. An example would be the loading cursor of Windows 7 Operating System. They are characterised by a circular ring or a section of the ring rotating round an origin.

We will try to create a loader that is shown below.

See the Pen Somewhat Win7 Loader by Tathagata Sengupta (@tathagata) on CodePen.

Here’s another demo, which is similar to the previous one.

The HTML

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="normstyle.css">
    </head>
    <body>
        <div id="loader"></div>
    </body>
</html>

Quite simple? Of course it is. Let’s have a look at the CSS that does all the work.

The CSS

body {
    margin:1em;
    background:#020202;
}

@keyframes loading { to {transform:rotate(360deg)} }
#loader:before {
    content:'';
    width:25px;
    height:25px;
    border-radius:25px 0px 0px 0px;
    background:#0059ff;
    transform-origin:25px 25px;
    animation:loading 2s linear 0s infinite;
}

#loader:after {
    content:'';
    width:35px;
    height:35px;
    border-radius:17.5px;
    position:absolute;
    top:12.5px; left:12.5px;
    background:#020202;
}

circular loader 1

Quadrant

width : x px ;
height : x px ;
border-radius : x px 0 0 0 ;

Circle

width : y px ;  /*less than 2x*/
height : y px ;
border-radius : 50% ;

Now shift both of them so that their centres lie at (x, x), i.e., shift the after block by (x – y/2 , x – y/2). Add akeyframe animation of rotating the before block about the origin by 360 degree at every interval and you have a simple rotating spinner.

Circular Loaders

Circular Loaders might be best understood as a set of repeated elements arranged in a circle. A sensation of movement is created by highlighting the successive elements after a delay.

Here is how a circular loader looks like. We will explain how to create such loaders in this section.

See the Pen Circular Loader 1 by Tathagata Sengupta (@tathagata) on CodePen.

You may check the Circular Loader 2 and Circular Loader 3, which look similar to this demo. In addition to that, here is a Facebook like loader too.

The main focus of this section is to place the different mini elements, here lists, at their precise locations. There are two methods for doing this —

  • Orthogonal Translation
  • Translation along rotated axes

HTML

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="circ1style.css">
    </head>
    <body>
        <div id="loader">
            <div class="loaderFace"></div>
            <ul class="bars">
                <li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
            </ul>
        </div>
    </body>
</html>

The list items will form the repeated elements of the loader. Number of elements will decide the location of each element.

CSS

This will include the positioning, orientation and the loading animation of various list items. The common shape of each element is written within the li block. It’s either a block or a cicle. Also we initially translate each element such that all of them coincide at a single point. This is achieved via margin property.

Translation :

  • Orthogonal Translation The example CSS is given below —
body{
    background:#ffffff;
}

@-webkit-keyframes load{
    from {opacity:1;}
    to {opacity:0;}
}

#loader .bars li{
    width:20px;
    height:20px;
    border-radius:10px;
    display:block;
    background:#6f6fff;
    float:left;
}

#loader .bars li:first-child{-webkit-transform:translate(60px, 0px); -webkit-animation:load 3s linear 0s infinite;}
#loader .bars li:nth-child(2){margin-left:-20px; -webkit-transform:translate(90px, 8.0385px); -webkit-animation:load 3s linear 0.25s infinite;}
#loader .bars li:nth-child(3){margin-left:-20px; -webkit-transform:translate(111.9615px, 30px); -webkit-animation:load 3s linear 0.5s infinite;}
#loader .bars li:nth-child(4){margin-left:-20px; -webkit-transform:translate(120px, 60px); -webkit-animation:load 3s linear 0.75s infinite;}
#loader .bars li:nth-child(5){margin-left:-20px; -webkit-transform:translate(111.9615px, 90px); -webkit-animation:load 3s linear 1s infinite;}
#loader .bars li:nth-child(6){margin-left:-20px; -webkit-transform:translate(90px, 111.9615px); -webkit-animation:load 3s linear 1.25s infinite;}
#loader .bars li:nth-child(7){margin-left:-20px; -webkit-transform:translate(60px, 120px); -webkit-animation:load 3s linear 1.5s infinite;}
#loader .bars li:nth-child(8){margin-left:-20px; -webkit-transform:translate(30px, 111.9615px); -webkit-animation:load 3s linear 1.75s infinite;}
#loader .bars li:nth-child(9){margin-left:-20px; -webkit-transform:translate(8.0385px, 90px); -webkit-animation:load 3s linear 2s infinite;}
#loader .bars li:nth-child(10){margin-left:-20px; -webkit-transform:translate(0px, 60px); -webkit-animation:load 3s linear 2.25s infinite;}
#loader .bars li:nth-child(11){margin-left:-20px; -webkit-transform:translate(8.0385px, 30px); -webkit-animation:load 3s linear 2.5s infinite;}
#loader .bars li:nth-child(12){margin-left:-20px; -webkit-transform:translate(30px, 8.0385px); -webkit-animation:load 3s linear 2.75s infinite;}

rotated axes

Suppose we have x elements we need to arrange in a circle of radius r pixels.

We have θ = 360/x

Translate every element by (r + r cos nθ , r + r sin nθ) where n = {0,1,…(n-1)}. Use a calculator for the values as accurate as possible.

  • Translation along Rotated Axes The example CSS is given below —
body{
    background:#ffffff;
    margin: 100px;
}

@-webkit-keyframes load{
    from {opacity:1;}
    to {opacity:0;}
}

#loader .bars li{
    width:5px;
    height:20px;
    display:block;
    background:#6f6fff;
    float:left;
}

#loader .bars li:first-child{margin-left:-5px; -webkit-transform:rotate(0deg) translateY(-20px);-webkit-animation:load 3s linear 0s infinite;}
#loader .bars li:nth-child(2){margin-left:-5px; -webkit-transform:rotate(30deg) translateY(-20px); -webkit-animation:load 3s linear 0.25s infinite;}
#loader .bars li:nth-child(3){margin-left:-5px; -webkit-transform:rotate(60deg) translateY(-20px); -webkit-animation:load 3s linear 0.5s infinite;}
#loader .bars li:nth-child(4){margin-left:-5px; -webkit-transform:rotate(90deg) translateY(-20px); -webkit-animation:load 3s linear 0.75s infinite;}
#loader .bars li:nth-child(5){margin-left:-5px; -webkit-transform:rotate(120deg) translateY(-20px); -webkit-animation:load 3s linear 1s infinite;}
#loader .bars li:nth-child(6){margin-left:-5px; -webkit-transform:rotate(150deg) translateY(-20px); -webkit-animation:load 3s linear 1.25s infinite;}
#loader .bars li:nth-child(7){margin-left:-5px; -webkit-transform:rotate(180deg) translateY(-20px); -webkit-animation:load 3s linear 1.5s infinite;}
#loader .bars li:nth-child(8){margin-left:-5px; -webkit-transform:rotate(210deg) translateY(-20px); -webkit-animation:load 3s linear 1.75s infinite;}
#loader .bars li:nth-child(9){margin-left:-5px; -webkit-transform:rotate(240deg) translateY(-20px); -webkit-animation:load 3s linear 2s infinite;}
#loader .bars li:nth-child(10){margin-left:-5px; -webkit-transform:rotate(270deg) translateY(-20px); -webkit-animation:load 3s linear 2.25s infinite;}
#loader .bars li:nth-child(11){margin-left:-5px; -webkit-transform:rotate(300deg) translateY(-20px); -webkit-animation:load 3s linear 2.5s infinite;}
#loader .bars li:nth-child(12){margin-left:-5px; -webkit-transform:rotate(330deg) translateY(-20px); -webkit-animation:load 3s linear 2.75s infinite;}

rotatory loader

Suppose we have x elements again. Rotate each element by a degree of n * (360/x) where n = {0,1,…(n-1)}.

Now, the new axes would be like in the figure 3. Translate the elements by a same length to get a uniform pin cushion structure. Rotation of axes is a relatively simpler approach compared to orthogonal translation. However, in cases when rotation is forbidden, the latter is the only solution.

Animation

Add a keyframe animation to all the list items. To get the desired moving effect, change their initial delay. Voila! You have your circular loader ready.

To conclude, I would like to point out that these are just basic loaders to get you started. A collection of these could be found in this collection which includes perspective methods, 3D transformations which requires additional calculations based on vectors and 3D coordinate systems. However, once you’ve mastered them, creativity would be the only barrier.

Speak Your Mind

*