A pure CSS spinning loader

The simplest possible loader I can think of is a spinning broken circle. With CSS you can create a circle simply by setting the border-radius of a div to 50%. You also need a few other CSS rules like the border-color, width and height (make sure they are the same!)

.loading {
  border: 10px solid red;
  border-radius: 50%;
  border-left-color: transparent;
  display: inline-block;
  height: 50px;
  width: 50px;
}

To break the circle, just remove one of the borders by making its colour transparent - I have removed boorder-left - and there you have it

To animate it you need a keyframes object with the state at the beginning and end of the cycle. Even better, you don’t even need the ‘from’ state, it is just the initial state as defined in the other styles. Then you refer to those keyframe with the animation rule

.loading {
  animation: 1s linear infinite gotofritz-spin;
  ....
}

@keyframes gotofritz-spin {
  to {
    transform: rotate(360deg);
  }
}

In the code sample below I have slightly rearranged the CSS, and introduced the backface-visibility: hidden property to force the animation in its own rendering layer. This is a performance enhancement that makes more sense if the spinner is animating over a complex background, and it means the background won’t need to be rerendered all the time.

See the Pen The Simplest React Loader - step 1 by gotofritz (@gotofritz) on CodePen.

Replacing the HTML with a functional React component

As a first step I will remove the HTML completely, introduce React and have it render the div that was priorly in the HTML. It will be a simple one line stateless, functional component, attached directly to the body

function Loading() {
  return <div classname="loading"></div>;
}

ReactDOM.render(
  <loading>,
  document.getElementsByTagName('body')[0]
);
</loading>

So the HTML is gone; now I need to make the CSS disappear, as I want to have a simple one file component that doesn’t make any assumptios about how the CSS is handled. For the first part I just turn the CSS into a JS object, and pass it to the component. I can even have some of the CSS set by props

function Loading({ size = 50} = props) {
    const style = {
        display: 'inline-block',
        width: `${size}px`,
        ...
    }
}
ReactDOM.render(
    <loading size="50">,
    document.getElementsByTagName('body')[0]
);
</loading>

The only thing left to add the animation itself to the component.

See the Pen The Simplest React Loader - step 2 by gotofritz (@gotofritz) on CodePen.

Adding keframes to the inline style of the React component

There are many (too many..?) ways to handle CSS with React components. But they all introduce dependencies, and I don’t want that. All of these solutions one way or another end up generating CSS on the fly and adding it to the document. I can do that as well; it’s just one line of CSS after all. I put that in the component, checking to see if the style already exists.

See the Pen The Simplest React Loader by gotofritz (@gotofritz) on CodePen.

And there you have it - the simplest of loaders, fairly customisable and all in one file, without dependencies. It’s not something I would use in production (although it wouldn’t be the end of the world if I did) but it’s great for quick prototyping.