Pre-loaders are a common sight in modern web design. As users we expect the web to be fast and fluid - we don’t like waiting for things. Pre-loaders offer visual feedback in the event of content being loaded, thereby managing expectations and reducing the chance of a user abandoning your website.
CSS3 Essentials for Creating Pre-loaders
Before we dive into building our collection of CSS3 pre-loaders, first I’ll be discussing some of the attributes of CSS3 which are essential for creating these type of pre-loaders.
Pseudo Elements :before
:after
Pseudo elements are really useful in helping creating CSS3 pre-loaders. Pseudo elements essentially create a fake element before or after the HTML element in question.
“Pseudo is derived from the Greek word pseudēs which means false.”
This is similar to creating an extra element that doesn't really exist however pseudo elements can be styled using CSS. These pseudo elements aren't a necessity for creating CSS3 pre-loaders but they do come in handy and allow us to use minimal markup.
Pseudo elements can be styled exactly the same way as you would any other HTML element the only difference being that you must specify a content
property. Without specifying this the pseudo element will not render. The content property can contain any text which may be useful if your pre-loader needs to contain words such as “Loading...” however if you don’t need any text content then you can just leave the content property blank.
CSS3 Animation
CSS pseudo elements are useful but not essential for creating CSS3 pre-loaders, but the animation property is. Without this the pre-loader would fail to animate and would just be a static visual - not very useful to indicate that the content is loading.
“The main component of CSS animations is @keyframes, the CSS rule where animation is created. Think of @keyframes as being stages along a timeline. Inside@keyframes, you can define these stages, each having a different style declaration.” - A beginners introduction to CSS animation
Note: before we jump into the demo's it might be worth noting that vendor prefixes are not included in the code snippets below. If you need the vendor prefixes then please see the codepen examples.
1. Audio Wave
The idea behind this pre-loader is to create an animation similar to an audio wave.
HTML
This is achieved by creating five spans, each one representing an audio bar.
<div id="preloader_1"><span></span><span></span><span></span><span></span><span></span></div>
CSS
The effect is achieved by animating the height of each span from 5px to 30px. The span also moves down on the Y axis by 15px to give the effect that it is growing from the centre.
#preloader_1{ position:relative; } #preloader_1 span{ display:block; bottom:0px; width: 9px; height: 5px; background:#9b59b6; position:absolute; animation: preloader_1 1.5s infinite ease-in-out; } #preloader_1 span:nth-child(2){ left:11px; animation-delay: .2s; } #preloader_1 span:nth-child(3){ left:22px; animation-delay: .4s; } #preloader_1 span:nth-child(4){ left:33px; animation-delay: .6s; } #preloader_1 span:nth-child(5){ left:44px; animation-delay: .8s; } @keyframes preloader_1 { 0% {height:5px;transform:translateY(0px);background:#9b59b6;} 25% {height:30px;transform:translateY(15px);background:#3498db;} 50% {height:5px;transform:translateY(0px);background:#9b59b6;} 100% {height:5px;transform:translateY(0px);background:#9b59b6;} }
By default the animation on each span happens at the same time. The Mexican wave effect is created by adding animation-delay
to each span with an offset of 2 milliseconds. Each span is targeted using the nth-child()
selector.
2. Circular Square
This pre-loader uses four squares which shift, rotate, change color and become circles.
HTML
It's created by using four spans. Each one is a circle/square and has its own animation applied to it.
<div id="preloader_2"><span></span><span></span><span></span><span></span></div>
CSS
All four of them transform from a square into a circle by adjusting the border-radius from 0px (square) to 20px (circle).
#preloader_2{ position: relative; left: 50%; width: 40px; height: 40px; } #preloader_2 span{ display:block; bottom:0px; width: 20px; height: 20px; background:#9b59b6; position:absolute; } #preloader_2 span:nth-child(1){ animation: preloader_2_1 1.5s infinite ease-in-out; } #preloader_2 span:nth-child(2){ left:20px; animation: preloader_2_2 1.5s infinite ease-in-out; } #preloader_2 span:nth-child(3){ top:0px; animation: preloader_2_3 1.5s infinite ease-in-out; } #preloader_2 span:nth-child(4){ top:0px; left:20px; animation: preloader_2_4 1.5s infinite ease-in-out; } @-keyframes preloader_2_1 { 0% {-transform: translateX(0px) translateY(0px) rotate(0deg); border-radius:0px;} 50% {-transform: translateX(-20px) translateY(-10px) rotate(-180deg); border-radius:20px;background:#3498db;} 80% {-transform: translateX(0px) translateY(0px) rotate(-360deg); border-radius:0px;} 100% {-transform: translateX(0px) translateY(0px) rotate(-360deg); border-radius:0px;} } @-keyframes preloader_2_2 { 0% {-transform: translateX(0px) translateY(0px) rotate(0deg);border-radius:0px;} 50% {-transform: translateX(20px) translateY(-10px) rotate(180deg);border-radius:20px;background:#f1c40f;} 80% {-transform: translateX(0px) translateY(0px) rotate(360deg);border-radius:0px;} 100% {-transform: translateX(0px) translateY(0px) rotate(360deg);border-radius:0px;} } @-keyframes preloader_2_3 { 0% {-transform: translateX(0px) translateY(0px) rotate(0deg);border-radius:0px;} 50% {-transform: translateX(-20px) translateY(10px) rotate(-180deg); border-radius:20px;background:#2ecc71;} 80% {-transform: translateX(0px) translateY(0px) rotate(-360deg);border-radius:0px;} 100% {-transform: translateX(0px) translateY(0px) rotate(-360deg); border-radius:0px;} } @-keyframes preloader_2_4 { 0% {-transform: translateX(0px) translateY(0px) rotate(0deg); border-radius:0px;} 50% {-transform: translateX(20px) translateY(10px) rotate(180deg); border-radius:20px;background:#e74c3c;} 80% {-transform: translateX(0px) translateY(0px) rotate(360deg); border-radius:0px;} 100% {-transform: translateX(0px) translateY(0px) rotate(360deg);border-radius:0px;} }
Each one also rotates and moves along the X & Y axis in opposite direction to its current position. The color of each span is also animated from a uniform purple to its own independent color. This gives the impression of the shapes merging from several circles into one square.
3. Crossing Shapes
The Crossing Shapes pre-loader is a single div that utilises the :before
and :after
pseudo elements that we talked about previously.
HTML
<div id="preloader_3"></div>
CSS
#preloader_3{ position:relative; } #preloader_3:before{ width:20px; height:20px; border-radius:20px; background:blue; content:''; position:absolute; background:#9b59b6; animation: preloader_3_before 1.5s infinite ease-in-out; } #preloader_3:after{ width:20px; height:20px; border-radius:20px; background:blue; content:''; position:absolute; background:#2ecc71; left:22px; animation: preloader_3_after 1.5s infinite ease-in-out; } @keyframes preloader_3_before { 0% {transform: translateX(0px) rotate(0deg)} 50% {transform: translateX(50px) scale(1.2) rotate(260deg); background:#2ecc71;border-radius:0px;} 100% {transform: translateX(0px) rotate(0deg)} } @keyframes preloader_3_after { 0% {transform: translateX(0px)} 50% {transform: translateX(-50px) scale(1.2) rotate(-260deg);background:#9b59b6;border-radius:0px;} 100% {transform: translateX(0px)} }
One animation is placed on #preloader_3:before
and another on #preloader_3:after
. Each animation changes into a different color at the opposite time. Similarly to the previous pre-loader each pseudo element changes from a circle to a square by animating the border-radius
property.
4. The Snake
The snake is made up of a collection of spans each one being styled to form a circle.
HTML
Here's the markup, but you could always try creating the snake pre-loader with three circles and rather than having several spans just use #preloader_4
div with :before
and :after
.
<div id="preloader_4"><span></span><span></span><span></span><span></span><span></span></div>
CSS
The animation is created by transforming the Y position of each animation by -10px and changing color from blue to yellow. To create the underlying shadow effect a drop shadow is added to each span which changes its vertical shadow size from 0px to 20px.
#preloader_4{ position:relative; } #preloader_4 span{ position:absolute; width:20px; height:20px; background:#3498db; opacity:0.5; border-radius:20px; -animation: preloader_4 1s infinite ease-in-out; } #preloader_4 span:nth-child(2){ left:20px; animation-delay: .2s; } #preloader_4 span:nth-child(3){ left:40px; animation-delay: .4s; } #preloader_4 span:nth-child(4){ left:60px; animation-delay: .6s; } #preloader_4 span:nth-child(5){ left:80px; animation-delay: .8s; } @keyframes preloader_4 { 0% {opacity: 0.3; transform:translateY(0px); box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.1);} 50% {opacity: 1; transform: translateY(-10px); background:#f1c40f; box-shadow: 0px 20px 3px rgba(0, 0, 0, 0.05);} 100% {opacity: 0.3; transform:translateY(0px); box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.1);} }
Similarly to pre-loader 1, by adding animation-delay
to each span and offsetting each span's delay by 2 milliseconds it creates the wave effect.
5. Spinning Disc
This is.. a spinny thing.
HTML
Here we simply use a single div for the central circle and :after
on that div to create the outer lines.
<div id="preloader5"></div>
CSS
Adding a border to the top and bottom and giving it a border-radius
of 50px creates the two outer lines. An animation is added to the main div, just to change the main div's color and create the rotation effect by adding transform: rotate()
. The :after
element animation is added to change the color of the outer border.
#preloader5{ position:relative; width:30px; height:30px; background:#3498db; border-radius:50px; animation: preloader_5 1.5s infinite linear; } #preloader5:after{ position:absolute; width:50px; height:50px; border-top:10px solid #9b59b6; border-bottom:10px solid #9b59b6; border-left:10px solid transparent; border-right:10px solid transparent; border-radius:50px; content:''; top:-20px; left:-20px; animation: preloader_5_after 1.5s infinite linear; } @keyframes preloader_5 { 0% {transform: rotate(0deg);} 50% {transform: rotate(180deg);background:#2ecc71;} 100% {transform: rotate(360deg);} } @keyframes preloader_5_after { 0% {border-top:10px solid #9b59b6;border-bottom:10px solid #9b59b6;} 50% {border-top:10px solid #3498db;border-bottom:10px solid #3498db;} 100% {border-top:10px solid #9b59b6;border-bottom:10px solid #9b59b6;} }
6. Glistening Window
We've gone a bit Microsoft on this one..
HTML
This pre-loader is created using a div and four spans to create each square.
<div id="preloader6"><span></span><span></span><span></span><span></span></div>
CSS
These squares are then positioned in a grid-like order. Animation is added to the main div to rotate the whole pre-loader. Another animation is added to the spans which scales them from 100% to 50%. We then add animation-delay
to each span to create the pulsing effect.
#preloader6{ position:relative; width: 42px; height: 42px; animation: preloader_6 5s infinite linear; } #preloader6 span{ width:20px; height:20px; position:absolute; background:red; display:block; animation: preloader_6_span 1s infinite linear; } #preloader6 span:nth-child(1){ background:#2ecc71; } #preloader6 span:nth-child(2){ left:22px; background:#9b59b6; animation-delay: .2s; } #preloader6 span:nth-child(3){ top:22px; background:#3498db; animation-delay: .4s; } #preloader6 span:nth-child(4){ top:22px; left:22px; background:#f1c40f; animation-delay: .6s; } @keyframes preloader_6_span { 0% { transform:scale(1); } 50% { transform:scale(0.5); } 100% { transform:scale(1); } }
Conclusion
The great advantage about using CSS3 pre-loaders over image pre-loaders is that they are scalable and retina ready. That means that no matter what device they are displayed on they will always be crisp, clean and future proof (though bear in mind that not all legacy browsers support CSS3 animation).
By understanding a few important CSS3 properties and techniques you should now be able to create your own CSS3 pre-loaders. They're fun to create and with a little bit of experimentation you can create some really cool animations to prevent users from leaving your website.
If you've created any cool pre-loaders recently then I'd love to see them! Feel free to leave your comments below.