Progress Bar

A native scroll progress indicator powered by CSS scroll-driven animations. The bar tracks the root scroll timeline and grows from left to right without JavaScript.

Progress bar component illustration

0 KB JavaScript

~20 CSS lines

scroll() timeline

fixed page indicator

Preview

BROWUI
MDN Web Docs
+

Scroll through the container to see the progress bar

The code

The markup

<div class="scroll-progress" aria-hidden="true"></div>

CSS mechanisms

/* ----------------------------------------------------------------------------
 * Scroll progress bar
 * ---------------------------------------------------------------------------- */

/**
 * Hidden by default so unsupported browsers do not show a static bar.
 * Custom properties expose the visual knobs without changing the mechanism.
 */

.scroll-progress {
  --scroll-progress-size: 4px;
  --scroll-progress-color: currentColor;
  --scroll-progress-z-index: 100;

  display: none;
}

/**
 * Enable the bar only when the browser supports scroll-driven animations.
 */

@supports (animation-timeline: scroll(root block)) {
  .scroll-progress {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    z-index: var(--scroll-progress-z-index);
    block-size: var(--scroll-progress-size);
    background: var(--scroll-progress-color);
    pointer-events: none;

    transform: scaleX(0);
    transform-origin: 0 50%;

    animation-name: scroll-progress-grow;
    animation-duration: 1ms;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: scroll(root block);
  }
}

/**
 * Endpoint for the progress animation: full width when fully scrolled.
 */

@keyframes scroll-progress-grow {
  to { transform: scaleX(1); }
}

Browser support

Benefits

Current limitations