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 Interactivity

Zola is wonderful. It builds quickly, it's extremely configurable, but it is (by design) not well suited for interactive elements or complex JavaScript. I hadn't thought I wanted that until I saw some on Amos's site. He ended up using iframes to manage that integration, which is a perfectly acceptable solution. But it did make me wonder: can we accomplish the same result without all of that nasty ugly HTML? Can we just write some clean JS and call it a day?

Let's find out…

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…