Scroll Progress Bar
Reading progress indicator that fills as you scroll — fixed at the top of the viewport with smooth spring physics
scrollprogressindicatorframer-motionreading
Install dependencies
$npm install framer-motionPreview
Source Code
"use client";
import { RefObject } from "react";
import { motion, useScroll, useSpring } from "framer-motion";
interface ScrollProgressBarProps {
position?: "top" | "bottom";
height?: number;
color?: string;
target?: RefObject<HTMLElement | null>;
className?: string;
}
export default function ScrollProgressBar({
position = "top",
height = 4,
color = "#6366f1",
target,
className = "",
}: ScrollProgressBarProps) {
const { scrollYProgress } = useScroll(
target ? { container: target as RefObject<HTMLElement> } : undefined
);
const scaleX = useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
restDelta: 0.001,
});
const positionStyle =
position === "top" ? { top: 0 } : { bottom: 0 };
return (
<motion.div
style={{
scaleX,
originX: 0,
height,
backgroundColor: color,
...positionStyle,
}}
className={`pointer-events-none fixed left-0 right-0 z-50 ${className}`}
aria-hidden="true"
/>
);
}