Dynamic Reading Progress Bar


Feb 10, 2025
1 minute read

I'm sure fjall-rs isn't the first tech blog to implement a dynamic reading progress bar, but it's the first the caught my eye. Implementing it was trivially easy, though there are some browser pitfalls to be aware of. Here it is, in full:

// Animate the progress bar
let progressBar = document.querySelector(".progress-bar");
if (progressBar) {
 let html = document.querySelector("html");
 let header = document.querySelector("header");
 const updateProgressBar = () => {
  // This is the only way I found to deal with the mobile address bar
  let effectiveScrollHeight = html.scrollHeight - window.innerHeight;
  // Only enable this when the post is big enough
  if (effectiveScrollHeight > 200) {
   let newHeight = Math.round(
    100 * (html.scrollTop / effectiveScrollHeight)
   );
   progressBar.style.width = `${newHeight}%`;
  } else {
   progressBar.style.width = "0";
  }
 };

 document.addEventListener("scroll", () => {
  updateProgressBar();
 });
 // Scroll events don't always fire when the window resizes
 document.addEventListener("resize", () => {
  updateProgressBar();
 });
}

.progress-bar {
  position: fixed;
  left: 0;
  top: 0;
  height: 3px;
  background: #5ca3ff;
  /* so you can click through */
  pointer-events: none;
  /* raise above everything else */
  z-index: 100;
  /* make the transition nice and smooth */
  transition: width 1s ease-in-out;
}

And I think the result is quite pleasing:


Recommended reading

Adding Videos to This Blog

Feb 10, 2025
1 minute read

I just added in the ability to render videos in my blog, and in so doing came across a question I hadn't considered before: how do I reserve space for a video that loads after the page does? Also, are videos loaded after page load, or what's the deal there?

Turns out: yes! You can reserve space for a video. In my case…