cover

4 February 2025

Building a Scroll Progress Bar

2m44s
svelte
scrollprogress
webdesign
frontend
blog-post

Today I want to share a neat little feature I added to my personal blog a scroll progress bar that shows readers how far they've gotten in the post. You know, that subtle line at the top or bottom of the page that fills up as you scroll? Let's build one together!

The Concept

The logic behind a scroll progress bar is actually pretty simple. We need to:

1. Track how far the user has scrolled

2. Calculate what percentage of the total scrollable content that represents

3. Update a visual element to reflect that percentage

While I'll show you how to implement this in Svelte, the core concept works in any framework or vanilla JavaScript. It's all about listening to the scroll event and doing some basic math.

The Implementation

Here's the complete code for a scroll progress bar component in Svelte:

Svelte

Progress.svelte
<script lang="ts">
  let scrolled = $state(0)
</script>

<svelte:window
  onscroll={() => {
    var winScroll = 
      document.body.scrollTop || document.documentElement.scrollTop
    var height = 
      document.documentElement.scrollHeight - 
      document.documentElement.clientHeight
    scrolled = (winScroll / height) * 100
  }}
/>

<div style="--scrolled: {scrolled}%;"></div>

<style>
  div {
    --primary: #00e3ba;
	
    --scrolled: 0%;
    position: fixed;
    bottom: 0;
    left: 0;
    height: 4px;
    background: var(--primary);
    opacity: 0.35;
    width: var(--scrolled);
  }
  
  /* MOVE BAR TO TOP ON MOBILE */
  @media only screen and (max-width: 900px) {
    div {
      top: 0;
      bottom: auto;
    }
  }
</style>

Let's break down what's happening:

The State

Svelte

<script lang="ts">
  let scrolled = $state(0)
</script>

We start by creating a reactive variable to track our scroll percentage.

The Scroll Logic

The svelte:window element lets us listen to window events. Our scroll handler does the math:

- Get how many pixels we've scrolled (winScroll)

- Calculate the total scrollable height (height)

- Turn that into a percentage

The Visual Bar

The div element uses CSS custom properties (variables) to make the width dynamic. As you scroll, the width updates to match the scroll percentage. I've made it semi-transparent and fixed to the bottom of the page (or top on mobile).

Wrapping Up

And there you have it! A simple yet effective way to add a scroll progress indicator to your blog. It's these little UI touches that can make your site feel more polished and user-friendly.

Remember, the best features are often the simplest ones - this entire implementation is less than 50 lines of code, but it adds a lot of value to the reading experience.

Happy coding! 🚀