Pothibo

Pure CSS-no-DOM loading indicator

Look all the solution and come back. All the "CSS Only" loading indicator have some sort of DOM insertion involved. Those solution are all cool and dandy when inside their respective demo environment but the shit hit the fans very quickly in production. Size restriction, legacy DOM structure, conflicting CSS styles, the list goes on.

So I needed a drop-in replacement. A solution that would only involve toggling a CSS class and be adaptable to pretty much any situation with no support for retard browsers.

A button

Start with a small button. It can be pretty much everything you want. I will use the space taken by the current button when the loading will appear. Bigger the button, bigger the loading indicator.

A button

CSS Background: More than meet the eyes

CSS support background gradients and this is the cornerstone of this technique. It uses the space taken by the button and replace the background with a gradient. Using the button above:

A button

Backgrounds can be repeated and this is exactly what happen with the gradient above. To achieve this effect, only 2 [+ vendor-prefixes] line of CSS are required.

background: -moz-linear-gradient(left, rgba(30,87,153,0.1) 0,rgba(78,136,193,0.1) 50%,rgba(79,137,194,0) 50%,rgba(125,185,232,0) 100%); background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(30,87,153,0.1)), color-stop(50%, rgba(78,136,193,0.1)), color-stop(50%, rgba(79,137,194,0)), color-stop(100%, rgba(125,185,232,0))); background: -webkit-linear-gradient(left, rgba(30,87,153,0.1) 0,rgba(78,136,193,0.1) 50%,rgba(79,137,194,0) 50%,rgba(125,185,232,0) 100%); background: -o-linear-gradient(left, rgba(30,87,153,0.1) 0,rgba(78,136,193,0.1) 50%,rgba(79,137,194,0) 50%,rgba(125,185,232,0) 100%); background: -ms-linear-gradient(left, rgba(30,87,153,0.1) 0,rgba(78,136,193,0.1) 50%,rgba(79,137,194,0) 50%,rgba(125,185,232,0) 100%); background: linear-gradient(to right, rgba(30,87,153,0.1) 0,rgba(78,136,193,0.1) 50%,rgba(79,137,194,0) 50%,rgba(125,185,232,0) 100%); background-size: 10px 100%;

Now, it looks like a curtain. Not really what I had in mind. What would be cool is if we could animate the background somehow. Gradient are not animatable, background-position is.

CSS Animations

CSS animations are like CSS functions. You add some rules to your object and use @keyframe rules. You can customize every step of your animation with these. In the example here, I only want to move the background enough so that it feels like an infinite loading. Above I set the background-size to 10px. That's the amount I want my background to move. The following function need to be added to your CSS.

@keyframes loading { to { background-position: 10px 0; } } @-webkit-keyframes loading { to { background-position: 10px 0; } } @-moz-keyframes loading { to { background-position: 10px 0; } } @-o-keyframes loading { to { background-position: 10px 0; } }

Again, it would be so much easier if everybody would drop the vendor-prefixes.

Now that the animation function is defined. Add the following animation rules to the button.

-webkit-animation-duration: 0.3s; -webkit-animation-name: loading; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -moz-animation-duration: 0.3s; -moz-animation-name: loading; -moz-animation-iteration-count: infinite; -moz-animation-timing-function: linear; -o-animation-duration: 0.3s; -o-animation-name: loading; -o-animation-iteration-count: infinite; -o-animation-timing-function: linear; animation-duration: 0.3s; animation-name: loading; animation-iteration-count: infinite; animation-timing-function: linear;

Notice the -animation-name. The value of this property is the function name you defined with @keyframes. Here's the button above with the animation set up.

A button

Now, you can toggle all those states by only toggling a CSS class on your button. No DOM manipulation! Check the demo below.

Demo

If you liked this post, follow me on Twitter!

Get more ideas like this to your inbox

You will never receive spam, ever.