Skip to content

Scroll Velocity

Rows of large text that drift sideways, speeding up and reversing with how fast the page is scrolled. Rows alternate direction.

Motionv0.1.0experimentalWCAG 2.2 AAView spec

Optional, and kept apart.

Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.

Scroll faster

The words follow you

import { ScrollVelocity } from "@rdloom/react";

export default function ScrollVelocityBasicExample() {
  return (
    <div className="w-full overflow-hidden py-6">
      <ScrollVelocity rows={["Scroll faster", "The words follow you"]} className="text-5xl font-bold" />
    </div>
  );
}

Installation

npx rdloom add scroll-velocity

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.

It also adds rdloom-motion.css next to your tokens and imports it from the tokens file, once: no setup, and no inline styles. The plain components you already use are untouched.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/scroll-velocity.json

Works, but without upgrade tracking, and you import the motion CSS yourself.

Usage

import { ScrollVelocity } from "@rdloom/react";

<div className="w-full overflow-hidden py-6">
  <ScrollVelocity rows={["Scroll faster", "The words follow you"]} className="text-5xl font-bold" />
</div>

Single row

Design systems that move

import { ScrollVelocity } from "@rdloom/react";

export default function ScrollVelocitySingleRowExample() {
  return (
    <div className="w-full overflow-hidden py-6">
      <ScrollVelocity rows={["Design systems that move"]} showPauseButton={false} className="text-6xl font-black" />
    </div>
  );
}

Slow

Gentle drift

Barely moving

import { ScrollVelocity } from "@rdloom/react";

export default function ScrollVelocitySlowExample() {
  return (
    <div className="w-full overflow-hidden py-6">
      <ScrollVelocity rows={["Gentle drift", "Barely moving"]} speed={25} velocityFactor={0.15} className="text-4xl font-semibold" />
    </div>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
rowsrequired

The text of each row.

readonly string[]none
speed

Resting speed in pixels per second.

number60
velocityFactor

How strongly page scrolling adds to the speed. 0 ignores scrolling.

number0.4
showPauseButton

Shows a visible Pause and Play button (WCAG 2.2.2).

booleantrue
pauseLabel

Text of the button while moving.

string"Pause"
playLabel

Text of the button while paused.

string"Play"
isPaused

Stops the animation and shows the text plainly. Moving content that lasts more than five seconds should be stoppable.

booleanfalse

Accessibility

Role text, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

Not interactive.

Screen readers announce

  • Each row is read once as ordinary text

What your code must do

  • The text is ordinary text in the page from the server render, readable with no JavaScript, and read once by screen readers
  • Decoration only: the animated layers are hidden from assistive technology and never take focus
  • Stands still for visitors who ask for less motion (prefers-reduced-motion), and can also be shown still with the rdm-still class or isPaused
  • In forced-colors (high contrast) mode the text is drawn in the system colours with no effect
  • Does not flash: nothing changes more than three times in a second (WCAG 2.3.1)
  • Optional: it is a separate component, so projects that do not add it carry none of its code
  • Moving content can be stopped: by isPaused, by the Pause button, and by anything inside rdm-still
  • Only the first copy of each row is in the accessibility tree; repeats are aria-hidden
  • Reduced motion gives static rows that can be scrolled by hand, with the repeats removed

Guidelines

Use it when

  • Large decorative words between page sections

Avoid it when

  • Content people must read closely
  • Navigation

Don't

  • Essential information in a moving row
  • Very high velocity factors

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-text-default
  • --rd-color-border-default
  • --rd-color-surface-default
  • --rd-radius-control