Avatar of Chris Coyier
Chris Coyier on

The following is a guest post by Timur Gafforov. Timur is the creator of – a site for building custom loading graphics. He ran another site that did this with GIFs, but was inspired to re-do it with CSS animation. This is that story.


The idea of appeared when I first learned about the keyframe animations in CSS. I had already had a project dedicated to loading animation graphics at the time, but this was much more inspiring as with native animations there are fewer limits than there is with raster images. Any size, any speed, any colors and other features with no server load. All the animations run with the loading of the page. This is what my users of had been requesting for years.

I created a first version of the site, but it was not very useful as it provided to little control over animations. A year after the launch, idea for a second version of the project came to me after seeing “Bouncy Animated Loading Animation” article here on CSS-Tricks. That gave me the inspiration to rework the project and launch the second version. The big idea was to provide users not only with the loading animations in pure CSS, but also give them more freedom to generate the animation they need with the least effort. And, voila, the second version is ready!

Thanks to Chris for the idea and Jacques for providing the Window 8 loading animation idea in the same post. Let us dig a little deeper now.

Reusing Tools

As I said, I had experience in loading image animations generator development, so I thought: why re-invent the wheel? I took some form goodies I used on – jQuery, Color Picker, Tigra Slider and some code snippets of my own (like my own “size scroller”). As a matter of fact, I make my own plugins often as this can be very useful in terms of code productivity and reduced code size. Only coding exactly what you need is often better than using one-size-fits-all solutions.

Now the form controls for choosing loader components are ready. I will skip that code here, as you can see it one the website and it’s pretty boring. We can move on to the “cream” of the application: the CSS animations generator.

Picking Options

Having taken some ideas from my own image animations and others from around the web I created several CSS loaders. I made a list of what should be changable by the user:

  • colors
  • animation speed
  • size
  • ability to reverse the animation
The UI for all choices.

Simple Example

Here is an example of one specific loader animation. I’ll keep the code un-prefixed for simplicity, but the code the site generates uses all the proper prefixes.

#noTrespassingOuterBarG {
  height: 20px;
  width: 160px;
  border: 1px solid #000000;
  overflow: hidden;
  background-color: #FFFFFF;

.noTrespassingBarLineG {
  background-color: #000000;
  float: left;
  width: 14px;
  height: 120px;
  margin-right: 24px;
  margin-top: -28px;
  transform: rotate(45deg);

.noTrespassingAnimationG {
  width: 236px;
  animation-name: noTrespassingAnimationG;
  animation-duration: 1.3s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;

@keyframes noTrespassingAnimationG {
  0% {
    margin-left: 0px;
  100% {
    margin-left:- 38px;
<div id="noTrespassingOuterBarG">
  <div id="noTrespassingFrontBarG" class="noTrespassingAnimationG">
    <div class="noTrespassingBarLineG">
    <div class="noTrespassingBarLineG">
    <div class="noTrespassingBarLineG">
    <div class="noTrespassingBarLineG">
    <div class="noTrespassingBarLineG">
    <div class="noTrespassingBarLineG">

More Considerations

Before developing any application, you must consider constraints and limits. In this case I decided these were reasonable:

  • Total animation duration can not be less than 0.
  • The size of the main and inner DIVs can not be less than 5px.
  • The animation should be work in as many browsers as possible.
  • The names of CSS classes must be different from what a user would usually use. I added a “G” as in Generated to the end of each class name.

A Function Per Animation

Everything else is pretty simple. Each animation has it’s own function with the same list of parameters: firstColor, secondColor, width, height, animationSpeed, isReverse and one common function that decides what function to call. Each control calls this common function upon change. Here is an example function:

function noTrespassing(firstColor, secondColor, width, height, animationSpeed, isReverse) {

  var toReturn='';

  if (isReverse) {
    var begin = Math.round(width*38/160) * (-1);
    var end = 0;
  else {
    var begin = 0;
    var end = Math.round(width*38/160) * (-1);

  toReturn += '<style>#noTrespassingOuterBarG{height:'+height+'px;width:'+width+'px;border:'+Math.ceil(height/20)+'px solid #'+firstColor+';overflow:hidden;background-color:#'+secondColor+'}.noTrespassingBarLineG{background-color:#'+firstColor+';float:left;width:'+Math.round(width*14/160)+'px;height:'+Math.round(width*120/160)+'px;margin-right:'+Math.round(width*24/160)+'px;margin-top:-'+Math.round(width*28/160)+'px;';

  toReturn += addPrefix('[prefix]transform:rotate(45deg);');

  toReturn += '}.noTrespassingAnimationG{width:'+Math.round(width*236/160)+'px;';

  toReturn += addPrefix('[prefix]animation-name:noTrespassingAnimationG;[prefix]animation-duration:'+animationSpeed+'s;[prefix]animation-iteration-count:infinite;[prefix]animation-timing-function:linear;');

  toReturn += '}#noTrespassingFrontBarG{}';

  toReturn += addPrefix('@[prefix]keyframes noTrespassingAnimationG{0%{margin-left:'+begin+'px;}100%{margin-left:'+end+'px;}}');

  toReturn += '</style><div id="noTrespassingOuterBarG"><div id="noTrespassingFrontBarG" class="noTrespassingAnimationG"><div class="noTrespassingBarLineG"></div><div class="noTrespassingBarLineG"></div><div class="noTrespassingBarLineG"></div><div class="noTrespassingBarLineG"></div><div class="noTrespassingBarLineG"></div><div class="noTrespassingBarLineG"></div></div></div>';

  return toReturn;

The variables in this function speak for themselves. You can see how the code of the animation is changed in regards to a particular form element change event. I guess there is no need to go deep into detail here, except for the addPrefix function. This function simply replaces the [prefix] part of the code with required prefixes through a loop of global prefixes array variable that is changed upon selection in the code dialog box.

That’s it! The rest you can find in the code source code of the project. We hope to receive some suggestions, questions, and of course, criticism.