Progress bar without JavaScript
Scroll Progress Bar - CSS only (with scroll-driven animations)
This demo shows how to build a scroll progress bar entirely in CSS, using scroll-driven animations animation-timeline: scroll(), custom properties, and no JavaScript for the progress itself.
The progress bar at the top of the page is driven by a CSS custom property --scroll that animates from 0 to 100 as the document scrolls.
This value is then reused to dynamically update the bar’s gradient; all handled by the browser’s animation engine.
What’s CSS-only here
- Scroll position tracking via
animation-timeline: scroll(root) - Progress calculation using a typed custom property
@property - Smooth, performant updates handled natively by CSS
- No JavaScript involved in computing or animating the progress bar
About the percentage counter
Displaying a live numeric value in pure CSS has long been considered difficult, especially when the value is driven by animations.
This demo uses a modern CSS approach combining typed custom properties
@property and CSS counters to display the scroll percentage without JavaScript.
- The scroll position animates a numeric CSS variable
--scroll - The variable is typed and interpolated using CSS Houdini
- A CSS counter converts the numeric value into readable text
- The displayed value is an integer approximation (0–100)
This technique relies on very recent CSS features and is currently supported only in modern Chromium-based browsers and Safari.
In production environments, JavaScript is still the most robust solution for dynamic numeric text — but this demo shows what modern CSS can already do.
Takeaway
- Modern CSS can track scroll position without JavaScript
- Typed custom properties enable real numeric interpolation
- CSS counters can expose animated values as readable text
- JavaScript remains the best choice for full cross-browser support
This pen explores the current frontier of what CSS can do today, without polyfills, hacks, or misleading shortcuts.