Skip to content

Reading Progress

A copy-paste scroll-driven component in pure HTML & CSS. Zero dependencies, framework-agnostic, MIT-licensed.

Scroll-DrivenHTMLCSSany framework

Scroll this panel.

The top bar tracks how far you have read.

It scales horizontally with scroll progress.

Pure CSS — no script involved.

Keep going to fill the bar.

Copy into your project

HTML
<!-- Reading progress bar driven by page scroll (CSS only) -->
<div class="nuda-scrollpb__track" role="progressbar"
     aria-label="Reading progress">
  <div class="nuda-scrollpb__bar"></div>
</div>
CSS
/* Reading Progress
   A top bar that fills as the document scrolls, using a native
   scroll-progress timeline. Animates transform: scaleX (GPU only),
   never width. Customize: --progress-color, --progress-height */

.nuda-scrollpb__track {
  --progress-color: #e4ff54;
  --progress-height: 4px;
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--progress-height);
  background: rgba(255, 255, 255, 0.06);
  z-index: 9999;
}

.nuda-scrollpb__bar {
  height: 100%;
  background: var(--progress-color);
  transform: scaleX(0);
  transform-origin: 0 50%;
  animation: nuda-scrollpb-fill linear;
  animation-timeline: scroll(root block);
}

@keyframes nuda-scrollpb-fill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Browsers without scroll timelines: leave a faint full bar. */
@supports not (animation-timeline: scroll()) {
  .nuda-scrollpb__bar { transform: scaleX(1); opacity: 0.5; }
}

@media (prefers-reduced-motion: reduce) {
  .nuda-scrollpb__bar {
    animation: none;
    animation-timeline: none;
    transform: scaleX(1);
  }
}

How to use Reading Progress

Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.

Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.

More scroll-driven components

← Browse all NudaUI components