Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Text

Pro

Shuffle for React

Text whose letters shuffle into place like a slot machine, each one sliding sideways through other letters before it lands. For React with Base UI, when a headline should land with a spin.

Framework

Shuffle spins every letter through a short reel: each one slides sideways through a couple of other letters, the text's own by default, and lands on itself, every other letter first and the rest just behind, so the word seems to deal itself into place. It plays once the text scrolls into view, and again whenever the pointer comes over it.

Use it for a short, bold headline: a product name, a game title, a launch word. To flip glyphs in place instead of sliding them, use Decrypted Text; for zeros and ones, Binary Text. Each letter is a window over a strip of letters slid by a CSS keyframe animation the install adds to your stylesheet, with no animation library; a replay switches the strip to a second copy of the keyframes, which starts it again. With reduced motion the text is plain.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { Shuffle } from "@/components/ui/shuffle";
<h1>
  <Shuffle text="Shuffle" />
</h1>

Demos

Characters

characters is what slides past each letter instead of the text's own letters: digits for an order number, symbols for a password screen. steps is how many slide past before the real letter lands, 2 by default.

Preview width

Direction

direction is the side the letters slide in from, in the text's reading direction: start, the default, or end. On a right-to-left page start is the right. trigger="mount" plays it as soon as the page shows it.

Preview width

Order

order is the order the letters land in: alternate, the default, lands every other letter, then the rest once those have mostly landed; random scatters them. duration is one letter's slide, 500 ms by default.

Preview width

Accessibility

Screen readers read the text once, from a visually hidden copy; the strips are hidden from them. Every letter starts and ends on itself and keeps its own width, so the word reads before, while it waits and after, and the line never shifts. With reduced motion nothing slides.

FAQ

Which letters slide past?

Without characters, the text's own letters, so the word seems to shuffle itself. Each one is picked by a small formula of the letter's place and the step, never at random, so the server and the browser draw the same strip.

When does it play again?

Each time the pointer comes over the text, once the last letter of the run before has landed, so a pointer that wanders in and out doesn't restart it halfway. replayOnHover={false} keeps it to the first run.

How is it different from Decrypted Text?

Decrypted Text swaps glyphs in place, many in quick succession, and settles them one after the other. Shuffle slides a few letters sideways past each window, easing to a stop like a reel, and lands every other letter first.

Which font suits it?

Any: it loads none and uses the text's own. A bold display face or uppercase letters, as in the demos, make the slide read best. In a proportional font each letter's window is its own width, so a wider letter sliding past is clipped to it.

What does it show without JavaScript?

The text, plain: with trigger="view" nothing would start the animation, so it doesn't play. With trigger="mount" it plays from CSS alone.

What happens with reduced motion?

The text shows as it is, and the pointer doesn't shuffle it.

API Reference

Shuffle

<span> data-slot="shuffle"

PropType
textstring

The text.

characters?string

The characters that slide past; the text's own letters, shuffled, when unset.

direction?"start" | "end"

The side the letters slide in from, in the text's reading direction.

Type
"start" | "end"
Default
"start"
duration?number

How long one letter's slide takes, in milliseconds. @default 500.

order?"alternate" | "random"

The order the letters land in: every other one, then the rest, or scattered.

Type
"alternate" | "random"
Default
"alternate"
replayOnHover?boolean

Whether the pointer coming over the text shuffles it again. @default true.

Default
true
stagger?number

The time between one letter and the next, in milliseconds. @default 50.

steps?number

How many letters slide past before the real one lands. @default 2.

Default
2
trigger?"view" | "mount"

When it first plays: once it scrolls into view, or as soon as the page shows it.

Type
"view" | "mount"
Default
"view"
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.

AttributeType
data-view?string

"in" when visible is true, otherwise "out".

CSS variableType
--shuffle-durationstring

One letter's slide (500ms).

--shuffle-staggerstring

The time between one letter and the next (50ms).

All 97 text effects