Using CSS to Add A Reading Progress Bar To My Site
The length of my posts can vary dramatically - some (like this one) are very short, whilst others are much, much longer.
Although I generally try to indicate how long a post is, once a reader is in, there isn't really a good way to know how much more of the post is left (the days of thick scrollbars are, thankfully, quite some way behind us).
So, I decided to add a small visual indicator - a coloured bar which creeps across the top of the page as you progress.
Most functionality on my site works without javascript so, ideally, I wanted the new indicator to be CSS only.
This post describes how to add a progress bar to a website without using javascript.
* * *
### The Mechanism
A new experimental property (`animation-timeline`) was added to CSS back in 2023. It allows us to bind animations to specific events (such as scrolling).
Essentially, this allows us to have CSS change the state of of an element depending on how far down the page the reader is.
* * *
### Implementing
I added a couple of `<div>`s to the bottom of my site's template, defining the progress bar and a wrapper for it:
<div class="progress-bar-container" aria-hidden="true">
<div class="progress-bar"></div>
</div>
Although it's presence _shouldn't_ upset screen-readers, I decided to play it safe and add `aria-hidden` to be sure that I wasn't degrading compatibility.
I then used CSS to stick the div to the top of the viewport:
.progress-bar-container {
position: fixed;
top: 0px;
width: 100%;
z-index: 999;
background: transparent;
}
I chose to make the background transparent, but it's also possible to set it to a colour and create a two-tone bar where one colour squashes the other as the reader progresses.
For the progress bar, we define height and the colour before binding it to a CSS animation:
.progress-bar {
height: 3px;
background: #00cfff;
animation-timeline: scroll(y);
animation-name: width;
}
Finally, we create the animation:
@keyframes width {
from { width: 0 }
to { width: 100% }
}
The result is a blue bar that creeps across the page as the reader scrolls:
* * *
#### Advanced Mode
I **did** briefly experiment with having Pac-Man work his way across eating dots:
<style type="text/css">
.progress-bar-container {
position: fixed;
top: 0px;
width: 100%;
z-index: 999;
/* Set the background to a dot that Pacman will eat */
background-image: url(/images/Documentation/css-reading-position-indicator/dot.png);
/* Repeat all the way across
and line them up with his gob */
background-repeat: repeat-x;
background-position: center;
}
/* The progress bar is almost the same as before but we set
the background to white to hide the eaten docs */
.progress-bar {
height: 30px;
background: white;
animation-name: width;
animation-timeline: scroll(y);
}
/* Style the pac-man image */
.progress-bar img {
height: 20px;
width: 20px;
/* We want him stuck to the right edge
of the div so that he advances as the
user scrolls */
display: block;
margin-left: auto;
}
</style>
<div class="progress-bar-container">
<div class="progress-bar">
<!-- Include the pacman image -->
<img src="/images/Documentation/css-reading-position-indicator/pac-man.gif">
</div>
</div>
The result looked like this:
With a bit of tweaking, I could have got rid of the trailing white bar, but I ultimately decided that the whole thing was too distracting and switched back to a solid colour.
* * *
#### Dark Mode
My site automatically switches if the reader has configured their OS (or, more accurately, their browser) to prefer dark mode.
Rather than white and blue, my dark mode uses black and yellow.
So, I also added some CSS **after** the definitions above to change the scroll-bar colour accordingly:
@media (prefers-color-scheme: dark) {
.progress-bar {
background: #fc0
}
}
* * *
### Caveats
Being able to do all of this without javascript is great, but there _are_ some gotchas.
The progress bar width is based on the full page rather than just the main content: if you've lots of footer content (or a comments section) it's going to count that. There doesn't seem to be a good way to address that in CSS.
Despite being a few years old, `animation-timeline` is still marked experimental. Although Firefox now supports it, developer tools will still warn you about it not being supported elsewhere:
Other than that, it's quite a simple quality-of-life addition to a website which sometimes features very long posts.
Using CSS to Add A Reading Progress Bar To My Site
Author: Ben Tasker
www.bentasker.co.uk/posts/documentation/gene...
#css #html #webdesign
0
0
0
0