CSS3 spinning preloader

How To Create A CSS3 Spinning Preloader

Is your project including a large images or video files?

Are you creating a long one page website and don’t want your visitors to stare at a blank or messy screen while everything is loading?

Learn how to create a nice CSS3 spinning preloader in this tutorial.

You might be also interested in How To Make Page Transitions in HTML – Barba.js and GSAP3 Tutorial

Related Screencast

We will deconstruct a slick preloader found on the CSS Awards Website of The Day created by AQuest Web Agency.

CSS3 spinning preloader

You can view this elegant preloader in action at www.cantinanegrar.it.

View Demo

Lets start with our HTML markup first.

1. Create HTML Markup

<div id="loader-wrapper">
	<div id="loader"></div>
</div>

These two containers are all we need for start.

#loader-wrapper will be a full width and height div covering the whole screen and #loader will be our spinning elements in the middle of the screen.

2. Position our preloader

CSS3 spinning preloader
#loader-wrapper {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 1000;
}
#loader {
	display: block;
	position: relative;
	left: 50%;
	top: 50%;
	width: 150px;
	height: 150px;
	margin: -75px 0 0 -75px;

	border: 3px solid #3498db;
	z-index: 1500;
}

#loader-wrapper is set to position fixed with a very high z-index to appear on top of any content.

#loader is positioned in the middle of the screen by left: 50%; top: 50%, but to position the center of this div in the middle of the screen we are setting negative top and left margin -75px.

75px is a half of the #loader width and height.

3. Create a nested elements

Now lets create another two nested elements for our inner circles.

#loader:before {
	content: "";
	position: absolute;
	top: 5px;
	left: 5px;
	right: 5px;
	bottom: 5px;
	border: 3px solid #e74c3c;
}
#loader:after {
	content: "";
	position: absolute;
	top: 15px;
	left: 15px;
	right: 15px;
	bottom: 15px;
	border: 3px solid #f9c922;
}

We are using :before and :after CSS3 pseudo elements and positioning them absolute.

As you can see, we are not defining any width or height on the nested squares. We are simply setting the top, left, right and bottom offset.

That gives us more flexibility.

If we decide to change the size of #loader later on, our nested elements would scale automatically.

4. Turn our squares into lines

CSS3 spinning preloader

To turn all our squares into lines we will simply change the border to transparent and only set the border-top-color.

/* change border to transparent and set only border-top to a solid color */
#loader {
	border: 3px solid transparent;
	border-top-color: #3498db;
}
#loader:before {
	border: 3px solid transparent;
	border-top-color: #e74c3c;
}
#loader:after {
	border: 3px solid transparent;
	border-top-color: #f9c922;
}

This will keep all the other sides of the squares transparent.

Next we’ll add some border-radius to get a more circular shape to our preloader. Add the following to each of the elements.

#loader {
	border-radius: 50%;
}
#loader:before {
	border-radius: 50%;
}
#loader:after {
	border-radius: 50%;
}

This will bend our lines and we can finally add some animations.

5. Add CSS3 animation

CSS3 spinning preloader

We will add the animation to each of our element and use two keyframes to rotate each line by 360deg.

/* copy and paste the animation inside all 3 elements */
/* #loader, #loader:before, #loader:after */
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;

/* include this only once */
@-webkit-keyframes spin {
    0%   {
        -webkit-transform: rotate(0deg);  /* Chrome, Opera 15+, Safari 3.1+ */
        -ms-transform: rotate(0deg);  /* IE 9 */
        transform: rotate(0deg);  /* Firefox 16+, IE 10+, Opera */
    }
    100% {
        -webkit-transform: rotate(360deg);  /* Chrome, Opera 15+, Safari 3.1+ */
        -ms-transform: rotate(360deg);  /* IE 9 */
        transform: rotate(360deg);  /* Firefox 16+, IE 10+, Opera */
    }
}
@keyframes spin {
    0%   {
        -webkit-transform: rotate(0deg);  /* Chrome, Opera 15+, Safari 3.1+ */
        -ms-transform: rotate(0deg);  /* IE 9 */
        transform: rotate(0deg);  /* Firefox 16+, IE 10+, Opera */
    }
    100% {
        -webkit-transform: rotate(360deg);  /* Chrome, Opera 15+, Safari 3.1+ */
        -ms-transform: rotate(360deg);  /* IE 9 */
        transform: rotate(360deg);  /* Firefox 16+, IE 10+, Opera */
    }
}

We will also set the animation ease to linear and tweak the duration of the animations for #loader and #loader:before.

#loader {
	-webkit-animation: spin 2s linear infinite;
	animation: spin 2s linear infinite;
}
#loader:before {
	-webkit-animation: spin 3s linear infinite;
	animation: spin 3s linear infinite;
}

This creates the final effect when all 3 lines come together every few seconds.

View Demo

Add preloading screen transition

Our preloader is looking cool, but shouldn’t it animate out when the page content is loaded?

Let’s learn that and more in the next tutorial.

Go to related tutorial

Final CSS

#loader-wrapper {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1000;
}
#loader {
    display: block;
    position: relative;
    left: 50%;
    top: 50%;
    width: 150px;
    height: 150px;
    margin: -75px 0 0 -75px;
    border-radius: 50%;
    border: 3px solid transparent;
    border-top-color: #3498db;
    -webkit-animation: spin 2s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
    animation: spin 2s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
}

#loader:before {
    content: "";
    position: absolute;
    top: 5px;
    left: 5px;
    right: 5px;
    bottom: 5px;
    border-radius: 50%;
    border: 3px solid transparent;
    border-top-color: #e74c3c;
    -webkit-animation: spin 3s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
      animation: spin 3s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
}

#loader:after {
    content: "";
    position: absolute;
    top: 15px;
    left: 15px;
    right: 15px;
    bottom: 15px;
    border-radius: 50%;
    border: 3px solid transparent;
    border-top-color: #f9c922;
    -webkit-animation: spin 1.5s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
      animation: spin 1.5s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
}

@-webkit-keyframes spin {
    0%   {
        -webkit-transform: rotate(0deg);  /* Chrome, Opera 15+, Safari 3.1+ */
        -ms-transform: rotate(0deg);  /* IE 9 */
        transform: rotate(0deg);  /* Firefox 16+, IE 10+, Opera */
    }
    100% {
        -webkit-transform: rotate(360deg);  /* Chrome, Opera 15+, Safari 3.1+ */
        -ms-transform: rotate(360deg);  /* IE 9 */
        transform: rotate(360deg);  /* Firefox 16+, IE 10+, Opera */
    }
}
@keyframes spin {
    0%   {
        -webkit-transform: rotate(0deg);  /* Chrome, Opera 15+, Safari 3.1+ */
        -ms-transform: rotate(0deg);  /* IE 9 */
        transform: rotate(0deg);  /* Firefox 16+, IE 10+, Opera */
    }
    100% {
        -webkit-transform: rotate(360deg);  /* Chrome, Opera 15+, Safari 3.1+ */
        -ms-transform: rotate(360deg);  /* IE 9 */
        transform: rotate(360deg);  /* Firefox 16+, IE 10+, Opera */
    }
}

Conclusion

Now we have a nicely animating CSS3 preloader. Play with the timing, border size and colors to create your own unique preloader.

Have you seen another cool CSS3 preloader or preloading animation sequence that you would like to be deconstructed?

Let me know in the comments.

Other preloading tutorials

65 thoughts on “How To Create A CSS3 Spinning Preloader

  1. Pedro Morales

    That is a great effect and looks very nice, but I was curious about if you could make them spin the other way around. It could be used for some very fun effects.

    Reply
    1. Petr Tichy Post author

      Hey Pedro, thanks for reading. Sure you can change the direction by changing 360deg to a negative value of -360deg. Share with us the fun effect you’re trying to create. Cheers

      Reply
      1. Nate

        I realize the thread is a bit old.. but if the tutorial request is still an offer:
        I think you should do one on turning different logos into loading animations.

        Reply
  2. ABS

    this is a great effect. thanks to share publicly. i have a little problem with this. when i’m shifting the loader in left section. its not adjust the size when i’m changing the resolution of screen. how can i make it responsive.
    [i increased the size of loader]

    Reply
  3. Daniel

    hi just a couple of querys

    how would i substute the lines for dots
    or change the lenght of the lines

    and im assuming that if you added an image reference in the wrapper you could have a “splash screen” effect

    Reply
  4. deepak

    hi there,
    is it possible to show this preloader effect only when the whole web site is loading. not when site’s post(or any other pages of the site) is being loading.??

    Regards
    deepak

    Reply
    1. Petr Tichy Post author

      Hi Deepak, you would need to write these rules in JavaScript or on the server.

      ie. If page = homepage include preloader html and css, else do nothing.

      Reply
  5. Heinz

    Hi Petr

    your spinner is just beautiful. I hope it is legal to use your code on my website. Once it these site is online I will post a link.
    My question concerns CPU performance.
    When switching the loader off (display: none ) will the animation still run in the backround, hence needing CPU power ?

    thanks Heinz

    Reply
  6. Zeeshaan

    I’m use this is weebly….. when i add this it’s not working… is not loading and just stop and show center of my website

    Reply
  7. Mattia Vorstenbosch

    Great tutorial, i like reverse engineering your projects to see if i can make sense of it all before reading the tutorial. I’m just weird like that :).

    Reply
  8. Anuj Shah

    I am using this with codeigniter but the problem is after loads this spinning preloader it display blank screen .. !!
    I want to know where it will redirected after loading this spinner !!

    Reply
  9. Vincent Teyssier

    Hi and thanks a lot for this super clear tutorial!

    I’ve implemented it on a test website. It is a heavy one. It takes approx 2s to load the DOM. The problem here is that before my loader appears, I can see that other parts of the DOM are created first. I can solve the problem by setting the opacity of the container to 0 and the background color to the same as the loader, but I’ll still have the colored circles not appearing before approx 0.5s.
    I’ve put the loader div on top of my html and my js on top of my jsfile : “$(document).ready(function() {…”

    Any idea why the loader does not display first ?

    Reply
    1. Petr Tichy Post author

      Hi Vincent, looks like your page is too heavy. You did the right thing by placing the preloader on top of your html.

      Looks like you need a more robust preloader like QueryLoader or ImagesLoaded.

      These preloader libraries will make sure that you display preloader screen first then in the background load the necessary assets and then show the loaded page.

      Hope that helps.

      Reply
  10. Vince

    Hi, nice code thanks !
    i’ve seen other method using json to show preloader with percentage of download of given files size. Do you think it could be easy to add something like this in your preloader ?
    See here :
    Example with percentage visible:
    http://www.gayadesign.com/scripts/queryLoaderPercentage/
    Thanks !

    Reply
  11. Whitney Anne Ideh

    Hey I just added this to my Dreamweaver site and everything looks perfect but the loader doesn’t disappear when the web page has fully loaded, how do I correct this?

    Thank you.

    Reply
    1. Petr Tichy Post author

      Hi Whitney, sounds like you have a javascript error and the loading class body from the body is not being removed. Check the developer console for any JS errors.

      Reply
  12. Shawn

    Thank you so much for this awesome tutorial! I am trying to implement it into my own web page. I added the HTML markup to my the HTML in my webpage. Then I created a .css file and put it in my /images folder. It contains all the CSS you posted at the end of your tutorial. Am I doing that correctly or am I missing something? Please help! Thanks =)

    Reply
    1. Petr Tichy Post author

      Hi Shawn, the css file usually goes into /css/ folder, but it doesn’t matter, the important part is to include a reference to it in your html. What exactly is not working for you?

      Reply
  13. Xyz

    Hello Pter,

    How can I change opacity to background div “loader-wrapper” ? I could not able to make it transparent.

    Reply
  14. Edinho Rodrigues

    I’m doing a loading with css3 and I am using this example, but I would like to leave an image on the static background, the logo of my company . Does anyone know how to do this?? Thank you

    Reply
  15. Melissa

    I found this immensely helpful! Super glad to not have to create a motion graphic and have CSS do the work instead

    Reply
  16. Hammed

    Thanks for the tutorials,

    Actually, I used different preloader and ran into a particular challenge, and then I Googled preloaders and found your tutrial, implemented and got the same challenge, It doesn’t stop loading. like a continuous loop.

    I have set the fadeout delay in the JS to 350 but it still, continuous loop.

    what else can I do to make it work.

    Thanks.

    Reply
  17. Ashwin

    Hi Peter…… How to add this preloader to our website…. this wasn’t working…. to my project…. it was giving me error…. can you please tell me what changes to do so that i can apply… to my project

    Reply
  18. Chidi

    Wow! great tut. Been wondering if there’s a way i could make a preloader with a name lets say a preloader spelling out ihatetomatoes for instance.

    thanks as i await a tut on this and hope i get notified when eventually its done

    cheers!!!

    Reply
  19. Joco

    Thank you so much, super helpful tutorial. Seeing that the preloader is powered by css3, please is there a way to make it show only once as the page is loaded. I have tried using JavaScripts sessionStorage function to disable it until a user closes his browser but it seems not to be working still even though the sessionStorage variable is been set.

    Thanks.

    Reply
  20. Sarah

    Hello!
    Everything works up until the loaded portion of my CSS. It seems my JavaScript possibly isn’t creating the loaded class properly, so it is never being called and the loading screen goes on forever. I used your same JavaScript, any thoughts on what could be causing this issue?
    Thanks!

    Reply
  21. jess

    i have too much headaches how to make the preloader on top of everything and i tried z-index equal to 99999 and it works.. thank you.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.