, , , ,


If you are certain that some pages or sections on your website/web application take some time to load, you would consider showing a loading GIF. Loading GIF visually communicates to the user/visitor that the page is loading and wait for it to complete. In the absence of these page loaders, the user/visitors might think that the website or application is inactive and might get frustrated and they might tend to keep clicking for the action again and again which might crash the website/application. Loading GIF is like a distraction which can actually make the wait seems much shorter.

Early Loading GIF

Till the introduction of CSS3 these loading GIF were of animated gif format. A Google search for loading gif or Ajax loading gif will get you a lot of images of such kind with a lot of variety and size. There are websites that let you create loading GIF online and download them to your project. Some of them are,


And if you are not satisfied with all of these and if you know Adobe Flash or Adobe Fireworks you could create one of your styles.

But after all it’s again an image. When you use this on your project, the application has to download this file and cache it on your browser. And in my experience these loading GIF itself take some time to get displays on the screen if they are dynamically inserted. With the features of CSS3 once could easily create animated loading GIF purely on CSS3.

CSS3 Loading GIF
Websites or web application took a shift from Desktops to mobile devices to tablet and that called for the need for light weight websites that loads quickly. Introduction of CSS3 made the website or web applications light weight and hence improved application performance a lot. These light weight website plays a vital role in attracting users to your website or web applications. CSS3 provides a lot of options out of the box like, animations, gradients, border radius, 2D transformation, custom font fact etc.

How to add spinner to your mark up? Here is the HTML,

<div class="spinner">
    <div class="bar1 large"></div>
    <div class="bar2 large"></div>
    <div class="bar3 large"></div>
    <div class="bar4 large"></div>
    <div class="bar5 large"></div>
    <div class="bar6 large"></div>
    <div class="bar7 large"></div>
    <div class="bar8 large"></div>
    <div class="bar9 large"></div>
    <div class="bar10 large"></div>
    <div class="bar11 large"></div>
    <div class="bar12 large"></div>

And add the CSS,

div.spinner {
    position: relative;
    width: 54px;
    height: 54px;
    display: inline-block;
    float: left;
    z-index: 10000;
    left: 40%;

div.spinner div.large {
    float: left;
    width: 7%;
    height: 20%;
    background: #8C8C8C;
    position: absolute;
    opacity: 0;
    -webkit-animation: fade 1s linear infinite;
    animation: fade 1s linear infinite;
    -moz-animation: fade 1s linear infinite;
    -webkit-border-radius: 50px;
    border-radius: 50px;
    -moz-border-radius: 50px;
    -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.2);
    box-shadow: 0 0 3px rgba(0,0,0,0.2);
    -moz-box-shadow: 0 0 3px rgba(0,0,0,0.2);

div.spinner div.bar1 {
    -webkit-transform:rotate(0deg) translate(0, -142%); 
    -webkit-animation-delay: 0s; 
    -moz-transform: rotate(0deg) translate(0,-142%); 
    -moz-animation-delay: 0s;
    transform: rotate(0deg) translate(0,-142%);
    animation-delay: 0s;
    -ms-transform: rotate(0deg) translate(0,-142%);

div.spinner div.bar2 {
    -webkit-transform:rotate(30deg) translate(0, -142%);
    -webkit-animation-delay: -0.9167s;
    -moz-transform: rotate(30deg) translate(0, -142%);
    -moz-animation-delay: -0.9167s;
    transform: rotate(30deg) translate(0, -142%);
    animation-delay: -0.9167s;
    -ms-transform: rotate(30deg) translate(0,-142%);
div.spinner div.bar3 {
    -webkit-transform:rotate(60deg) translate(0, -142%);
    -webkit-animation-delay: -0.833s;
    -moz-transform: rotate(60deg) translate(0, -142%);
    -moz-animation-delay: -0.833s;
    transform: rotate(60deg) translate(0, -142%);
    animation-delay: -0.833s;
    -ms-transform: rotate(60deg) translate(0,-142%);
div.spinner div.bar4 {
    -webkit-transform:rotate(90deg) translate(0, -142%);
    -webkit-animation-delay: -0.75s;
    -moz-transform: rotate(90deg) translate(0, -142%);
    -moz-animation-delay: -0.75s;
    transform: rotate(90deg) translate(0, -142%);
    animation-delay: -0.75s;
    -ms-transform: rotate(90deg) translate(0,-142%);
div.spinner div.bar5 {
    -webkit-transform:rotate(120deg) translate(0, -142%);
    -webkit-animation-delay: -0.667s;
    -moz-transform: rotate(120deg) translate(0, -142%);
    -moz-animation-delay: -0.667s;
    transform: rotate(120deg) translate(0, -142%);
    animation-delay: -0.667s;
    -ms-transform: rotate(120deg) translate(0,-142%);
div.spinner div.bar6 {
    -webkit-transform:rotate(150deg) translate(0, -142%);
    -webkit-animation-delay: -0.5833s;
    -moz-transform: rotate(150deg) translate(0, -142%);
    -moz-animation-delay: -0.5833s;
    transform: rotate(150deg) translate(0, -142%);
    animation-delay: -0.5833s;
    -ms-transform: rotate(150deg) translate(0,-142%);
div.spinner div.bar7 {
    -webkit-transform:rotate(180deg) translate(0, -142%);
    -webkit-animation-delay: -0.5s;
    -moz-transform: rotate(180deg) translate(0, -142%);
    -moz-animation-delay: -0.5s;
    transform: rotate(180deg) translate(0, -142%);
    animation-delay: -0.5s;
    -ms-transform: rotate(180deg) translate(0,-142%);
div.spinner div.bar8 {
    -webkit-transform:rotate(210deg) translate(0, -142%);
    -webkit-animation-delay: -0.41667s;
    -moz-transform: rotate(210deg) translate(0, -142%);
    -moz-animation-delay: -0.41667s;
    transform: rotate(210deg) translate(0, -142%);
    animation-delay: -0.41667s;
    -ms-transform: rotate(210deg) translate(0,-142%);
div.spinner div.bar9 {
    -webkit-transform:rotate(240deg) translate(0, -142%);
    -webkit-animation-delay: -0.333s;
    -moz-transform: rotate(240deg) translate(0, -142%);
    -moz-animation-delay: -0.333s;
    transform: rotate(240deg) translate(0, -142%);
    animation-delay: -0.333s;
    -ms-transform: rotate(240deg) translate(0,-142%);
div.spinner div.bar10 {
    -webkit-transform:rotate(270deg) translate(0, -142%);
    -webkit-animation-delay: -0.25s;
    -moz-transform: rotate(270deg) translate(0, -142%);
    -moz-animation-delay: -0.25s;
    transform: rotate(270deg) translate(0, -142%);
    animation-delay: -0.25s;
    -ms-transform: rotate(270deg) translate(0,-142%);
div.spinner div.bar11 {
    -webkit-transform:rotate(300deg) translate(0, -142%);
    -webkit-animation-delay: -0.1667s;
    -moz-transform: rotate(300deg) translate(0, -142%);
    -moz-animation-delay: -0.1667s;
    transform: rotate(300deg) translate(0, -142%);
    animation-delay: -0.1667s;
    -ms-transform: rotate(300deg) translate(0,-142%);
div.spinner div.bar12 {
    -webkit-transform:rotate(330deg) translate(0, -142%);
    -webkit-animation-delay: -0.0833s;
    -moz-transform: rotate(330deg) translate(0, -142%);
    -moz-animation-delay: -0.0833s;
    transform: rotate(330deg) translate(0, -142%);
    animation-delay: -0.0833s;
    -ms-transform: rotate(330deg) translate(0,-142%);

@-webkit-keyframes fade {
    from {opacity: 1;}
to {opacity: 0.25;}

@keyframes fade{

jQuery plug-in
In the sections above I wanted you to know about the CSS3 option for creating a loading GIF. But, I will not recommend you to duplicate the above code, because it will make the DOM feel heavy. The above HTML code is like a dead code almost all the time and get active only when there is some delayed events on the page. We should dynamically insert this HTML code to the container where you need to show the animated loading GIF and remove it one the DOM rendering is completed. To achieve this lets write a very basic jQuery plug-in.

(function($) {
    $.fn.jSpinner = function(action, options) {
        if (action === "show") {
            var spinner = createMarkup(this,options);
        if (action === "hide") {
    function createMarkup(element,options) {
        var top = $(element).height()/2;
        var left = $(element).width()/2;
        var spinner = $('<div class="spinner" style="top:' + top + 'px;left:'+left+'px">' +
                '<div class="bar1 ' + options.css + '"></div>' +
                '<div class="bar2 ' + options.css + '"></div>' +
                '<div class="bar3 ' + options.css + '"></div>' +
                '<div class="bar4 ' + options.css + '"></div>' +
                '<div class="bar5 ' + options.css + '"></div>' +
                '<div class="bar6 ' + options.css + '"></div>' +
                '<div class="bar7 ' + options.css + '"></div>' +
                '<div class="bar8 ' + options.css + '"></div>' +
                '<div class="bar9 ' + options.css + '"></div>' +
                '<div class="bar10 ' + options.css + '"></div>' +
                '<div class="bar11 ' + options.css + '"></div>' +
                '<div class="bar12 ' + options.css + '"></div>' +
        return spinner;



The two input params are,

  1. action : The possible options are show to display the spinner on to the element specified and ‘hide’ to remove the spinner from the specified element
  2. params: You could send additional parameters, like in my example i’m sending custom CSS to have my look and feel for the spinner



Tested on following browsers

chrome-50 firefox-50 ie-50 safari-50

Above code is very basic level of jQuery, to make you understand the possibility of using CSS3 spinner as a jQuery plug-in. The extendibility of this CSS3 animated loading GIF jQuery plug-in depends on your application use case.

Hope this would have been informative.