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.