Updated on 23. October 2020
The original title of this post was 'Why and how to make a content specific loading animation'. I've recently learned that these are really called skeleton loaders, so I've updated the title and some of the content accordingly.

Here for the how and not the why? The code is at the bottom of the article or in the CodePen.

CodePen Embed

Klick below to show the CodePen as an embed. CodePen will set set several Cookies in your Browser.

CodePen.io Privacy Policy

In a world were the JAM Stack is more and more prevalent and agile data has to be send to the user without reloading the whole page, AJAX calls are a good way to improve the usability of a page.

This is, however not without challenge to us front-end designers as we have to think about how to show the user that fresh data is loading and soon to be displayed at a given space on the page. Some pages even load the entire content through an API call and it would be detrimental to show the user a blank page and have them guessing whether or not the page is actually going to display something.

A quick fix is to implement a spinner that indicates that something is happening. A better fix is, to use a skeleton loader that already teases the upcoming content and gives the user an idea what’s about to happen. It not only shows that content is coming, it also can indicate what content the user can expect and fills the space that will be occupied by the content later, avoiding page jumping and user confusion.

An assumption is made

To implement a skeleton loader, we have to guess what kind of content the page is loading. But in my experience we usually have a pretty good understanding, what data the page is about to receive. A headline and teaser text within a blogroll for example.

We then abstract the the respective data-elements (say headline and text) and display boxes and primitive shapes in the spaces the loading data would occupy.


If filled with an motion effect, the resulting animation gives the user a pretty good idea what to expect:


To achieve this visual effect, we first have to rebuild the boxes as DOM elements.

<article class="wrapper">
  <h1 class="headline loading-grad"></h1>
  <div class="line loading-grad"></div>
  <div class="line loading-grad"></div>
  <div class="line line--half loading-grad"></div>

We have one headline and three lines, on that spans only some fraction of the width.

The CSS to space them out, like in the example shown above, is as follows:

.wrapper {
  box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.5);
  padding: 2rem;
  margin: 20px auto;
  border-radius: 10px;
  background: #292d3e;
  width: 800px;
  height: 250px;
  overflow: hidden;
  box-sizing: border-box;
  .headline {
    margin: 0;
    box-sizing: border-box;
    height: 55px;
    border-radius: 5px;
    margin-bottom: 1.1rem;
  .line {
    height: 23px;
    border-radius: 3px;
    margin-bottom: 0.6rem;
    &--half {
      width: 70%;

I usually try to separate my CSS into reusable bits. This is why I put the loading animation into its own loading-grad class so that it can come into effect on different components.

.loading-grad {
  background: linear-gradient(
      to right,
      rgba(0, 0, 0, 0),
      rgba(0, 0, 0, 0),
      rgba(255, 255, 255, 0.12),
      rgba(0, 0, 0, 0),
      rgba(0, 0, 0, 0)
    ) repeat-x;
  background-size: 400% 100%;
  overflow: hidden;
  animation: scroll 1.5s infinite;

@keyframes scroll {
  100% {
    background-position: 100% 0%;

At first we supply the DOM elements that will have the loading animation with a new background - an linear-gradient with an height of 100% of the element but a 400% width. The gradient is basically transparent (hence the rgba) but with an white shading in the middle. The entire background is then moved via a CSS animation from the right to the left, resulting in an pleasant loading animation seen above. Dont forget the overflow hidden, that hides the background-excess, though.

The CSS class that we’ve now implemented can be reused with any type and constellation of content-boxes.

As always if you want to have a look at the code from the examples above or have a slab at it yourself, fork my CodePen, you are very much welcome to! Hit me up with your own variations on twitter.com/eliasguenther, I’d love to see what you come up with! Have a good one!

The creation of this post was made possible by coffee.
Buy me a coffee