shadcn.io is not affiliated with official shadcn/ui
Container Text Flip sets one word of a headline in a box and flips it to the next, again and again: the outgoing word fades into a blur, the box grows or shrinks to the next word's width, and the new word comes into focus inside it letter by letter. It pauses while the pointer is over it.
Use it for the word of a hero line that should read like a badge or a key: what a product makes things, who it's for. For a word that changes without a box and holds its widest width, use Flip Words or Rotating Text. A small timer counts the turns; at each one it reads the box's width and the next word's, laid out unseen, and a CSS transition runs between them, while CSS keyframe animations the install adds to your stylesheet bring the letters in, with no animation library. With reduced motion the words swap in place and the box simply fits each one.
Installation
Usage
import { ContainerTextFlip } from "@/components/ui/container-text-flip";<h2>
Make your websites <ContainerTextFlip words={["better", "modern", "beautiful"]} />
</h2>Demos
Colors
The box is the component itself, so its className styles it: a background, a border colour, a radius, a shadow. Here it takes the theme's primary colour; the letters keep the text colour you give it.
Timing
duration is how long each word stays, 3000 ms by default, and stagger the time between one letter coming in and the next, 30 ms.
Accessibility
Screen readers read every word once, as a list (better, modern, beautiful), from a visually hidden copy; the flipping letters are hidden from them, so they never hear a word change mid-sentence. The words stop while the pointer is over them, for anyone reading slowly, and with reduced motion they swap without blurring and the box changes size at once.
FAQ
How does the box know the next word's width?
The next word is always laid out, unseen and out of the way, inside the component. At each turn the timer reads the box's width and that word's, sets one and then the other, and a CSS transition on the width runs between them. Once it's done the box goes back to fitting its word on its own, so a font that loads late or a heading that changes size never leaves it the wrong width.
Does the text after it move?
Yes, as the box grows and shrinks, the way the box is meant to. Put it at the end of a line, as in a headline, and nothing moves at all; for a word that changes in the middle of a sentence without moving the rest, use Flip Words.
How do I change the box?
With className: bg-primary text-primary-foreground border-primary for a filled badge, rounded-full for a pill, shadow-none to drop its inner edge. The padding scales with the text, so the box fits a label as well as a hero line.
Does it pause?
Yes, while the pointer is over it, and it waits a full duration again once the pointer leaves. With a single word it never flips.
API Reference
ContainerTextFlip
<span> data-slot="container-text-flip"
wordsstring[]
The words, shown in turn from the first; a word may be a few words.
duration?number
How long each word stays, in milliseconds. @default 3000.
- Default
3000
stagger?number
The time between one letter coming in and the next, in milliseconds. @default 30.
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.
data-turn?string--container-text-flip-staggerstring
The time between one letter coming in and the next (30ms).
Related
Flip Words
CyclingThe same swap without the box
Rotating Text
CyclingWords that roll through like a reel
- Pro
Morph Text
CyclingWords that melt into each other
- Pro
Typing Text
EntranceType each option out instead
Highlight Text
DecorativeA band of colour behind a phrase
Gradient Text
DecorativeColour that flows through one word