component :: Read Progress Bar
The .readProgressBar component creates a reading progress bar at the top of
the page that represents the user’s scroll position, growing as the user
scrolls down and decreasing as they scroll up. This helps users understand
their progress through the content and how much remains to be read. This component uses pure CSS when supported by the browser, and has a polyfill for browsers that don’t support animation-timeline.
(Scroll this page to see the component in action.)
| File Name | class | Source |
|---|---|---|
component.ReadProgressBar.css | .readProgressBar | Github |
HTML
Custom properties
The following custom properties are available in the default theme:
| Property | Description |
|---|---|
--readProgressBar-height | Progress bar height. |
--readProgressBar-color | Progress bar background color. |
Examples
Astro Component
---import ReadProgressBar from '../components/ReadProgressBar.astro';---<ReadProgressBar />HTML
<div class="readProgressBar" aria-hidden="true"><div></div></div>If you’re using HTML and would like to us the polyfill for browsers that don’t support
animation-timeline, add the following JavaScript to your code:function throttle(func, delay) {let lastCall = 0;let timerId;return function (...args) {const now = new Date().getTime();if (now - lastCall < delay) {clearTimeout(timerId);timerId = setTimeout(() => {lastCall = now;func.apply(this, args);}, delay);} else {lastCall = now;func.apply(this, args);}};}function supportsScrollTimeline() {return CSS.supports("animation-timeline: scroll(y)");}function updateProgressBar() {const bar = document.querySelector(".readProgressBar > div");if (!bar) return;const scrollTop = window.scrollY || document.documentElement.scrollTop;const docHeight = document.documentElement.scrollHeight - window.innerHeight;const progress = docHeight > 0 ? scrollTop / docHeight : 0;bar.style.width = progress * 100 + "%";}function enableJSProgressBar() {const bar = document.querySelector(".readProgressBar > div");if (!bar) return;// Remove any inline width set by CSS animationbar.style.animation = "none";bar.style.animationTimeline = "none";updateProgressBar();const throttledUpdate = throttle(updateProgressBar, 10);window.addEventListener("scroll", throttledUpdate, { passive: true });window.addEventListener("resize", throttledUpdate);}if (typeof window !== "undefined" && !supportsScrollTimeline()) {document.addEventListener("DOMContentLoaded", enableJSProgressBar);}