This project demonstrates how to build a scroll progress bar and percentage indicator using only CSS, powered by scroll-driven animations, typed custom properties (CSS Houdini), and CSS counters.
No JavaScript is used to track, compute, or animate scroll progress.
⚠️ This is an advanced, experimental CSS demo.
Intended for learning, exploration, and showcasing modern CSS capabilities — not as a production-ready replacement for JavaScript yet.
👉 Live demo https://nojsscrollbar.mobiwise.dev
👉 Live demo on CodePen
https://codepen.io/mobiwise/pen/pvbjwYv
Modern CSS can now react directly to scroll position using scroll timelines.
Instead of listening to scroll events in JavaScript, this demo binds an animation directly to the document scroll using:
animation-timeline: scroll(root);The animation drives a typed numeric custom property, which is then reused to:
- Fill a progress bar
- Display a numeric percentage
- Keep all UI elements perfectly synchronized
animation-timeline: scroll(root);- Binds animation progress to scroll position instead of time
- The animation runs from 0% to 100% as the document scrolls
- No JavaScript event listeners required
@property --scroll {
syntax: "<number>";
inherits: false;
initial-value: 0;
}Why this matters:
- Enables real numeric interpolation
- Without
@property, CSS variables are treated as untyped tokens - Allows smooth, continuous updates during animation
background: linear-gradient(to right, blue calc(var(--scroll) * 1%), transparent 0);--scrollanimates from0to100- Converted into a percentage when used in the gradient
- Fully handled by the browser’s animation engine
Displaying live numbers in pure CSS has traditionally been difficult.
This demo uses CSS counters + typed properties:
counter-reset: scroll-value calc(var(--scroll));
content: counter(scroll-value) "%";How it works:
- The animated numeric value updates a CSS counter
- The counter converts it into readable text
- The displayed value is an integer approximation (0–100)
No JavaScript string manipulation required.
✔ Scroll position tracking
✔ Progress calculation
✔ Smooth animation updates
✔ Numeric percentage display
✔ Zero JavaScript for scroll logic
JavaScript is used only for the optional 3D text effect (DepthText), which is unrelated to scroll tracking.
- Chromium-based browsers (Chrome, Edge, etc.)
- Safari (recent versions)
- Firefox ❌
(animation-timeline: scroll()is not implemented yet)
A graceful fallback message is displayed for unsupported browsers.
While this demo works well in modern browsers:
- JavaScript remains more robust and portable
- CSS counters only expose integer values
- Browser support is still evolving
For production systems requiring full compatibility and precision, JavaScript is still the recommended solution.
This project is about exploring what CSS can already do today.
- Modern CSS can track scroll position without JavaScript
- Scroll-driven animations unlock new UI patterns
- Typed custom properties enable real numeric interpolation
- CSS counters can expose animated values as text
- The gap between CSS and JavaScript capabilities is shrinking
This project intentionally uses:
- CSS Houdini features
- Scroll timelines
- Modern color spaces (OKLCH)
- Advanced layering and feature detection
No polyfills. No hacks. No fake “CSS-only” tricks.
- DepthText (CSS-based 3D text layers):
https://depthtext.mobiwise.dev
https://github.com/MobiWise-dev/DepthText
MIT — use, fork, break, remix, and experiment freely.
Author
MobiWise.dev