Scroll Text Highlight
Reading highlight that turns text from pale grey to solid foreground, character by character (or word by word), as you scroll.
Loading preview…
npx shadcn@latest add https://webberui.com/r/scroll-text-highlight.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<ScrollTextHighlight />
Installation
npx shadcn@latest add https://webberui.com/r/scroll-text-highlight.jsonOr, once registries are configured in components.json, install it as @webberui/scroll-text-highlight.
Usage
Inside a nested scroll container, pass the container's ref to container:
import * as React from "react";
import { ScrollTextHighlight } from "@/components/ui/scroll-text-highlight";
export function Example() {
const scrollerRef = React.useRef<HTMLDivElement>(null);
return (
<div ref={scrollerRef} className="h-[300px] overflow-y-auto">
<div className="py-40">
<ScrollTextHighlight
container={scrollerRef}
text="Text that lights up character by character as you scroll."
className="text-xl font-semibold"
/>
</div>
</div>
);
}When the window itself is the scroll container, container can be omitted:
<ScrollTextHighlight
by="word"
text="Scroll to reveal."
className="text-4xl font-bold"
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | — | The text to highlight as you scroll |
by | "char" | "word" | "char" | Smallest unit of highlighting |
container | RefObject<HTMLElement> | — | Ref of the nested scroll container; omit to use the window as the scroll container |
className | string | — | Extra styles (set font size and text color here) |
How it works
useScroll({ target, container, offset: ["start end", "end start"] })yieldsscrollYProgress, the scroll progress of the target text from entering the bottom of the container to leaving the top- Each character (or word) is assigned a
[start, end]sub-range by index, anduseTransformmaps progress ontoopacity, turning them one by one from pale grey to solid foreground - Character mode splits on graphemes, so emoji and combining characters are never broken apart
- The text inherits
currentColor(the foreground color), which naturally reads as light grey while faded; set font size and text color viaclassName
Accessibility
- The complete text is rendered
sr-onlyfor assistive technology, and the per-character animation layer is markedaria-hidden, so nothing is announced twice - When the user has "reduce motion" enabled at the system level, the text renders statically in full foreground color