Skeleton Loader in Pure CSS

Skeleton Loader in Pure CSS

Featured on Hashnode

As promised in the last article, I'll be making a skeleton loader in this one.

What is a skeleton loader?

There are other names for this type of loader, but I think Skeleton Loader is quite fitting. It is basically the skeleton version of a component. So, before the actual content has been loaded, we show a rough outline of what is about to be shown.

Like this:

Sounds easy enough, right? Well, it is.

The HTML

The HTML for this one is going to be quite simple. When making a real skeleton loader, you'd of course have to adjust it to the content it will be the skeleton for. For the purpose of this article though, we'll just use a title and some content.

This is what we'll be working with:

<div class="container">
  <div class="placeholder title"></div>
  <div class="placeholder content"></div>
</div>

As you can see, we have a container element and two child elements with a shared class of .placeholder and their individual class names .title and .content.

We use the .placeholder class to style the actual skeleton component, and the individual class names are there to set the height and width of the respective skeleton.

The CSS

So... The structure of this article will be slightly different than the previous ones. There is a bit more CSS this time around. So, instead of explaining one line of CSS at a time, I'll explain each block of CSS. I think that'll be more manageable for both you and me.

The container

The container styles will be quite simple. You can actually change this however you want. The important thing here is that I've omitted the height to make it use the height of its children.

.container{
  width: 300px;
  padding: 10px;
  background: #eee;

  margin: auto;
}

The placeholder

The placeholder is where the magic happens. It's what will be taking up the space of the, yet to be loaded, content.

This is what the CSS should look like:

.placeholder{
  position: relative;
  background: #ccc;
  border-radius: 3px;

  overflow: hidden;
}

The most important parts of the CSS above is position: relative and overflow: hidden.

Both of these rules are there to manage the reflection animation. The relative positioning means we can set a position: absolute on a child, and it will use the parent's boundaries instead of the documents. This will become clearer later.

We're also hiding the elements overflow because the reflection animation will go past the inner box of the container and we want it to be hidden when it does.

The reflection

For the reflection, we'll use the pseudo-element ::after. We use it to avoid having to add another element for each of our placeholders.

This is the CSS for the actual reflection element.

.placeholder::after{
  content: "";
  position: absolute;

  height: 100%;
  width: 100px;
  left: -100px;
  top: 0;

  background: linear-gradient(to right, transparent, #ffffff70, transparent);
  animation: reflect 800ms ease-out infinite;
}

As you can see, the first thing we do is add some content. This is required for pseudo-elements like ::before and ::after to be displayed.

We also set the position to absolute. This is so we have good control over the position of the element. It lets us use the top, right, bottom, and left rules. In this case, we are only using the left and top rules.

We also set the height to be 100% and the width to just 100px. The left rule is set to -100px to hide the entire element at the beginning of our animation.

You can play around with the animation property however you want. The important part is that you keep the infinite animation-iteration-count.

The content

All we need to do for the .title and .content is to give them some height and width. You can change this however you want, but I've chosen to make the .title slightly less wide than the .content.

.title{
  width: 80%;
  min-height: 20px;

  margin-bottom: 10px;
}
.content{
  width: 100%;
  min-height: 60px;
}

The animation

Now, the animation is really simple. Just like the previous articles, we only specify the to property. Here, we make the reflection element go 100 pixels past the edge of its container.

We add that 100 pixels because that is the width of the reflection element. This makes sure that the entire reflection is hidden before the animation restarts.

@keyframes reflect{
  to{
    left: calc(100% + 100px);
  }
}

Putting it all together

That's it! Now, let's put everything together to see the result.

The HTML

<div class="container">
  <div class="placeholder title"></div>
  <div class="placeholder content"></div>
</div>

The CSS

.container{
  width: 300px;
  padding: 10px;
  background: #eee;

  margin: auto;
}
.placeholder{
  position: relative;
  background: #ccc;
  border-radius: 3px;

  overflow: hidden;
}
.placeholder::after{
  content: "";
  position: absolute;

  height: 100%;
  width: 100px;
  left: -100px;
  top: 0;

  background: linear-gradient(to right, transparent, #ffffff70, transparent);
  animation: reflect 800ms ease-out infinite;
}
.title{
  width: 80%;
  min-height: 20px;

  margin-bottom: 10px;
}
.content{
  width: 100%;
  min-height: 60px;
}

@keyframes reflect{
  to{
    left: calc(100% + 100px);
  }
}

Conclusion

As with the previous articles in this series, this has been a rather simple task to accomplish with just CSS and HTML. The point is that we don't need a JS animation library to create simple animations like these.

Knowing just a little bit about the @keyframes rule in CSS opens a lot of doors for you. It is not only simple to use but also very performant, even on lower-end devices.

The best way to learn something is by doing it yourself, without following a guide. So, open your editor and start writing CSS animations.