Scroll Progress Rail
A reading-progress rail that fills as you scroll — zero JavaScript, driven by animation-timeline: scroll() (the sibling of view(): scroll() tracks the scroll container's own progress instead of one element's visibility, so it's the right primitive for progress bars, scroll-linked marquees, and parallax, not element-enter reveals). Real, current, sourced browser support as of this run: Chrome/Edge unflagged since Chrome 115 (July 2023); Safari since Safari 26 (September 2025, with 26.5 in June 2026 fixing progress-accuracy bugs). Firefox does NOT support it in stable — still behind the layout.css.scroll-driven-animations.enabled flag, Nightly-only by default, a named Interop 2026 priority — so this is not yet Baseline; the @supports fallback below leaves the rail fully filled (not broken, not empty) on Firefox and any other unsupported browser. This is not scroll-jacking: it never calls preventDefault or touches scroll position, it only reads it — native scrolling, touch, trackpad, and keyboard all behave exactly as normal. (Vanilla example: live iframe preview + HTML/CSS tabs — scroll inside the box.)
<div class="spr-frame">
<div class="spr-bar"></div>
<div class="spr-scroller" tabindex="0" aria-label="Scrollable demo content">
<div class="spr-block">01</div>
<div class="spr-block">02</div>
<div class="spr-block">03</div>
<div class="spr-block">04</div>
</div>
</div>How it works
Scroll Progress Rail is a hand-built scroll component in plain HTML and CSS — no React, no Tailwind, no framework at all. Paste it into any site as-is and it stays performant on real devices. It's free — copy the code above and ship it.
← Browse all components