Scroll Velocity

Rows that loop sideways at a calm speed and run faster while the page scrolls. All the rows of a group read one shared scroll speed, turn around when the page scrolls up and lean slightly into their speed. Scroll the page to drive the examples.

For one large line of text, Scroll Text Marquee is lighter. Scroll Velocity is for a stack of rows, with text, chips or pictures, that should move as one group.

Examples

Two rows of text

The second row runs the other way. Both lean into their speed while the page scrolls and stand up again when it stops.

Plan the weekWrite it downShip on Friday
Review in pairsKeep the notesStart again

Rows of pictures

Any content can loop. Pictures keep straight with lean={false}.

Lavender hills under a yellow sun
Green hills under an orange sun
Terracotta hills under a red sun
Grey hills under a pale sun
Mauve hills under a pink sun
Olive hills under a yellow sun
Indigo hills under the moon
Blue hills under a yellow sun

Installation

npx shadcn@latest add https://ui.ndekocode.dev/r/motion-scroll-velocity.json

Component API

ScrollVelocity

Reads the scroll speed once for every row inside it.

PropTypeDefaultDescription
childrenReact.ReactNodeOne or more ScrollVelocityRow.
containerRefRefObject<HTMLElement | null>A scrolling element to follow instead of the page.
reverseOnScrollUpbooleantrueTurns every row around while the page scrolls up, until it scrolls down again.
leanbooleantrueSlants the rows into their speed, up to 6 degrees.
fadebooleantrueFades both ends of the rows.
classNamestringClasses for the group, a vertical flex column.

ScrollVelocityRow

PropTypeDefaultDescription
childrenReact.ReactNodeOne copy of the row's content. It is repeated as many times as the row needs to stay filled.
speednumber40Speed at rest, in pixels per second. Scrolling at 1000 pixels per second makes it five times faster.
direction'left' | 'right''left'The direction at rest.
gapnumber32Space between two copies, in pixels.
classNamestringClasses for the row, for example its text size.

Accessibility and motion

  • The rows move through motion values only: nothing re-renders while they run.
  • Rows move only while the group is on screen and the tab is visible, and a frame after a long pause never throws them forward.
  • One copy of each row is read by screen readers and reached by the keyboard; the repeats are hidden from both.
  • With reduced motion, the rows stand still and show their content from the start.
  • Scroll pieces belong on marketing pages. A row that keeps moving needs a way to stop for people who find it distracting: reduced motion stops it here, and a page that relies on it can offer a pause control as well.

Credits

Inspired by the scroll based velocity of Magic UI, rebuilt on motion values with rows that fill themselves and a shared scroll reading.