4 February 2025
Building a Scroll Progress Bar
Reading time: 2m 44s

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! 🚀