Skip to content

Scroll Progress

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

Scroll EffectsHTMLCSSJavaScriptany framework
Scroll Progress

Copy into your project

HTML
<div class="nuda-scroll-progress" role="progressbar"
     aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"
     aria-label="Reading progress">
  <div class="nuda-scroll-progress__bar"></div>
</div>
CSS
/* Scroll Progress
   Reading progress bar fixed at the top of the page.
   Customize: --progress-color, --progress-height */

.nuda-scroll-progress {
  --progress-color: #e4ff54;
  --progress-height: 3px;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--progress-height);
  background: rgba(255, 255, 255, 0.06);
  z-index: 9999;
}

.nuda-scroll-progress__bar {
  height: 100%;
  background: var(--progress-color);
  width: 0%;
  border-radius: 0 2px 2px 0;
  transition: width 0.1s linear;
}

@media (prefers-reduced-motion: reduce) {
  .nuda-scroll-progress__bar {
    transition: none;
  }
}
JavaScript
/* Scroll Progress — Updates the bar width based on scroll position. */

(function () {
  var bar = document.querySelector('.nuda-scroll-progress__bar');
  var wrapper = document.querySelector('.nuda-scroll-progress');
  if (!bar || !wrapper) return;

  function update() {
    var scrollTop = window.scrollY || document.documentElement.scrollTop;
    var docHeight = document.documentElement.scrollHeight - window.innerHeight;
    var progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
    bar.style.width = progress + '%';
    wrapper.setAttribute('aria-valuenow', String(Math.round(progress)));
  }

  window.addEventListener('scroll', update, { passive: true });
  update();
})();

How to use Scroll 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 effects components

← Browse all NudaUI components