shadcn.io is not affiliated with official shadcn/ui
Scroll Velocity slides rows of text sideways without end, every other row the other way, and ties them to the page's scroll: scroll down and each row is pushed along its way, faster the faster you scroll; scroll up and it's held back, even turned round. Each row repeats its text enough to fill a wide screen, so it never shows a gap or a seam.
Use it for a bold band of words between the sections of a landing page, a portfolio's headline or a ticker. For text that flows along a curve, use Curved Loop. It's CSS only: keyframe animations slide the rows, and a scroll-driven animation adds the push from the page's scroll position, with no scroll listener and no animation library. Chrome, Edge and Safari 26 tie the rows to the scroll; in other browsers, such as Firefox, they simply slide. With reduced motion they hold still.
Installation
Usage
import { ScrollVelocity } from "@/components/ui/scroll-velocity";<ScrollVelocity texts={["Build fast", "Ship faster"]} />Demos
Rows
Each text in texts is a row, and every other row runs the other way. intensity is how hard scrolling pushes them: subtle, medium (the default, about half a pixel for each pixel scrolled) or strong, here. Each row is data-slot="scroll-velocity-row", so rows can be styled from outside: here every other one is muted.
Ticker
separator draws a mark between copies, a part of its own (data-slot="scroll-velocity-separator"), and speed is the time a row takes to move by one character: 300 ms by default, 150 here for a quick ticker band.
Accessibility
Screen readers read each row's text once, from a visually hidden copy; the moving copies are hidden from them. The rows stop sliding while the pointer is over them, for anyone reading slowly; scrolling still pushes them, since then the reader is the one moving them. With reduced motion they hold still, push and all.
FAQ
Which browsers tie the rows to the scroll?
Those with CSS scroll-driven animations: Chrome and Edge 115 and later, and Safari 26 and later. In the others, such as Firefox today, the rows slide at their own pace and ignore the scroll; nothing else changes.
How does it follow the scroll without a scroll listener?
The push is a CSS animation whose clock is the page's scroll position (animation-timeline: scroll(root)) rather than time: every stretch scrolled moves a row on by one copy. Added to the slide, the row speeds up while you scroll and settles back when you stop, without any script.
Does it follow a panel that scrolls on its own?
No: it follows the page's own scroll. Inside a panel that scrolls by itself, or a page in a frame, the rows simply slide.
Which way do the rows go?
The first leftwards, the next rightwards, and so on; on right-to-left text, each the other way, so it flows its reading way. Scrolling down pushes every row its own way, and scrolling up holds it back.
Why is there never a gap?
Each row repeats its text to at least 400 characters, more than a wide screen shows even in small type, and moves by exactly one copy before starting again, which looks just as it did. Set rows in the size you like: the copies scale with the font.
API Reference
ScrollVelocity
<span> data-slot="scroll-velocity"
textsstring[]
One row each, moving in turn one way and the other.
intensity?"subtle" | "medium" | "strong"
How hard scrolling pushes the rows: about a quarter, a half or all of the distance scrolled.
- Type
"subtle" | "medium" | "strong"- Default
"medium"
separator?string
Drawn between one copy of a row's text and the next, such as ✦ or •.
speed?number
The time a row takes to move by one character, in milliseconds; lower is faster.
- Default
300
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
--scroll-velocity-intensitystring
How far a row moves for each pixel scrolled (0.5).
--scroll-velocity-speedstring
The time a row takes to move by one character (300ms).
Related
- Pro
Curved Loop
MotionA marquee along a curve
- Pro
Circular Text
MotionA ring that turns on its own
- Pro
Dot Matrix Text
DecorativeA ticker lit on a grid of dots
- Pro
Rolling Text
CyclingLetters that roll over in place
- Pro
Spiral Text
MotionText coiled into a turning spiral
- Pro
Outline Text
DecorativeHollow letters for big display rows