Tiny scroll progress bar for long posts
Tiny Reading Progress Bar for Long Posts
This tiny snippet adds a slim “reading progress” bar at the top of the viewport for long posts. As the visitor scrolls down, the bar fills from left to right. It’s a small UX touch that helps people feel oriented on long articles and know how much is left without hunting for the scrollbar.
Because it’s just a single fixed bar and a short script, it works well on blogs, documentation pages, tutorials, and long-form landing pages. There are no external dependencies and it stays out of the way of your layout and content.
Copy-paste snippet (CSS, HTML & JavaScript)
The snippet below includes the styles, the progress bar markup, and a tiny script that keeps everything in sync as the user scrolls:
<style>
/* Tiny scroll progress bar for long posts */
/* Container bar fixed at the top */
#vibe-scroll-progress {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 3px; /* make it taller if you want */
background: rgba(0, 0, 0, 0.05);
z-index: 9999;
pointer-events: none; /* don’t block clicks */
}
/* The filling part */
#vibe-scroll-progress-inner {
width: 0%;
height: 100%;
background: linear-gradient(90deg, #A829A7, #000);
transform-origin: left center;
transition: width 0.08s linear;
}
/* Optional: add a small offset to your layout’s top spacing if needed */
body {
padding-top: 3px; /* match the bar height if your header is flush to the top */
}
</style>
<!-- Place this near the top of your <body> -->
<div id="vibe-scroll-progress">
<div id="vibe-scroll-progress-inner"></div>
</div>
<script>
(function () {
var outer = document.getElementById('vibe-scroll-progress');
var inner = document.getElementById('vibe-scroll-progress-inner');
if (!outer || !inner) {
return; // element missing, nothing to do
}
function updateScrollProgress() {
var doc = document.documentElement;
var body = document.body;
// How far we’ve scrolled
var scrollTop = doc.scrollTop || body.scrollTop || 0;
// Total scrollable distance
var scrollHeight = (doc.scrollHeight || body.scrollHeight || 0) - doc.clientHeight;
if (scrollHeight <= 0) {
inner.style.width = '0%';
return;
}
var progress = (scrollTop / scrollHeight) * 100;
// Clamp between 0 and 100
if (progress < 0) progress = 0;
if (progress > 100) progress = 100;
inner.style.width = progress.toFixed(2) + '%';
}
// Run on load + scroll + resize
window.addEventListener('scroll', updateScrollProgress, { passive: true });
window.addEventListener('resize', updateScrollProgress);
document.addEventListener('DOMContentLoaded', updateScrollProgress);
// Initial call in case the page is short or already scrolled
updateScrollProgress();
})();
</script>
How to use it
Drop the <style> block and the
<div id="vibe-scroll-progress"> markup into your layout (usually near
the top of <body>) and paste the JavaScript just before your closing
</body>. Once it’s in place, any long page that uses that layout will
automatically show the progress bar as people scroll.
By default, it:
- Sticks a 3px bar to the top of the viewport.
- Fills the inner bar from 0% to 100% based on scroll position.
- Listens to
scrollandresizeso it stays accurate. - Uses
pointer-events: noneso it never blocks clicks or links.
If you don’t want the extra top padding, you can remove the
body { padding-top: 3px; } rule or adjust it to match your existing header
height. The bar is fixed and doesn’t replace your navigation; it simply sits above it.
Customizing the look
You can tweak a few easy knobs to better match your design:
-
Height: change
height: 3px;to 2px or 4px (or more) if you want a thinner or thicker bar. -
Colors: swap the
linear-gradientfor a solid color like#000, or use your brand colors for the fill. -
Position: move
top: 0;tobottom: 0;if you’d rather show the progress at the bottom of the viewport. -
Animation feel: adjust
transition: width 0.08s linear;for a snappier or smoother fill effect.
Where it works best
This pattern shines on pages where visitors scroll through a lot of content and want a quick sense of “how far along” they are. Good candidates include:
- Long guides and tutorials.
- Docs pages with multiple sections.
- Case studies and long-form sales pages.
- Any article where you want to give a subtle progress cue.
Because it’s just a single fixed bar and a couple of event listeners, it’s light enough for everyday use and doesn’t feel like a heavy plugin. You keep full control over the styles and behavior, and you can remove it anytime by taking out the snippet.
Comments (0)
No comments yet — be the first.