Vercel Snap Text
A scroll-driven text list that snaps exactly to each item. The active item scales up with an optional prefix, others fade and indent — all animated with Motion springs.
Installation
Pro components require registry authentication. Add your Unlumen UI Pro key as UNLUMEN_LICENSE_KEY in your .env.local file and follow the setup guide.
File Structure
Usage
import { VercelSnapText } from "@/components/unlumen-ui/vercel-snap-text";
<VercelSnapText
items={["the platform", "the brand", "the future"]}
prefix="We Design"
className="w-full h-screen"
/>;How it works
The component renders two layers inside a single container:
-
Scroll driver — an invisible
overflow-y: scrolloverlay withscroll-snap-type: y mandatory. Each item gets a full-height snap section so the browser always stops exactly on an item boundary. No JavaScript rounding required. -
Visual layer — a spring-animated track that moves to center the active item. Each row animates its horizontal offset (Motion spring), font size, and opacity based on its distance from the current scroll position.
API Reference
VercelSnapText
itemsstring[]—List of strings to cycle through.
prefix?string""Text prepended before the active item label (e.g. "We Design").
itemHeight?number96Height of each item row in pixels. All rows share this height — it is the snap unit.
stiffness?number200Spring stiffness for the track animation. Higher = snappier.
damping?number28Spring damping for the track animation. Higher = less bounce.
className?string—Additional CSS classes. Set a height (e.g. h-screen) on the root.
Credits
Inspired by the scroll-snap text effect seen on vercel.com. Thanks to the Vercel design team for the original idea.
Notes
- The component requires a fixed height on the root (e.g.
h-screen,h-[600px]). Without it, the scroll driver has no height and snapping won't work. - The invisible scroll overlay uses
scroll-snap-type: y mandatorywith each item as a full-height snap section. The browser handles snapping natively — no JS rounding needed. - The track animation uses a Motion spring (
stiffness: 280,damping: 30,mass: 0.8by default). Increasestiffnessfor snappier transitions, increasedampingto reduce bounce. itemHeightdefines the height of each row in the visual layer. All items share this height — it's the snap unit. Adjust it based on your font size.- Non-active items fade out proportionally to their distance from the current index (
opacity = 1 - dist × 0.82, minimum0.15). - The
prefixtext is always visible and doesn't animate. Only the item list scrolls. - Font size uses
clamp(1.75rem, 4vw, 4.5rem)— it scales responsively. Override it via className if you need a different size. - Scrollbar is hidden via
scrollbarWidth: "none"and-ms-overflow-style: none. The scroll area is fully invisible. - A
ResizeObserverkeepssectionHeightin sync with the container — no stale measurements after window resize.
Keep in mind
Most components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.
This component is part of Unlumen UI [ Pro ]
Includes advanced motion, patterns, and premium support.