shadcn.io is not affiliated with official shadcn/ui
Morph Text changes one word into the next without going anywhere: the outgoing letters swell and dissolve while the next word's letters condense where they stood, one after the other, and both words blur through the middle of the change, so the text seems to melt into its replacement. It cycles through its texts on its own, holds the width of the widest, and pauses while the pointer is over it.
Use it for a hero word that changes in place, or a short status that moves through its stages. For words that roll through a window like a reel, use Rotating Text; to lift each word away and raise the next, Flip Words; to slide the same letters into new places, Anagram Text. A small timer counts the turns and CSS keyframe animations the install adds to your stylesheet morph the letters, with no animation library; the blur is on each whole word, not on every letter, so a long word costs no more than a short one. With reduced motion the words swap in place.
Installation
Usage
import { MorphText } from "@/components/ui/morph-text";<h1>
<MorphText texts={["Beautiful", "Composable", "Yours"]} />
</h1>Demos
Label
At a label's size it reads as a status that changes. duration is how long each text stays, 2400 ms by default, and stagger the time between one letter morphing and the next, 25 ms; 0 morphs the whole word at once.
Blur
--morph-text-blur is how soft the words get in the middle of the change, 8px by default. A small one keeps the letters legible as they cross; a large one, with a slower stagger, turns the change into a haze.
Accessibility
Screen readers read every text once, as a list (Beautiful, Composable, Yours), from a visually hidden copy; the morphing letters are hidden from them, so they never hear a word change mid-sentence. The texts stop while the pointer is over them, for anyone reading slowly, and with reduced motion they swap without blurring or scaling.
FAQ
What happens when the texts have different lengths?
Each letter crosses over with the letter in the same place in the next text; where one text runs longer, its extra letters simply fade in or out. Nothing is padded, and every text is laid out in the same place, unseen, so the widest holds the space and the sentence around it never moves.
Is the blur expensive?
No more than two blurs at a time, whatever the length: the blur is on the outgoing and the incoming word as wholes, and only while they change. The letters move by opacity and scale alone.
How do I style the changing text?
Give it a className, such as font-bold text-primary: it applies to every text. The blur is a CSS variable, so [--morph-text-blur:4px] in the same className sets it.
API Reference
MorphText
<span> data-slot="morph-text"
textsstring[]
The texts, shown in turn from the first; a text may be a few words.
duration?number
How long each text stays, in milliseconds. @default 2400.
- Default
2400
stagger?number
The time between one letter morphing and the next, in milliseconds;
0 morphs the whole text at once.
- Default
25
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--morph-text-blurstring
How soft the words get mid-morph (8px).
--morph-text-staggerstring
The time between one letter morphing and the next (25ms).
Related
Rotating Text
CyclingWords that roll through a window
Flip Words
CyclingEach word lifts away for the next
- Pro
Anagram Text
CyclingThe same letters slide to new places
- Pro
Container Text Flip
CyclingA boxed word that resizes to fit
- Pro
Caps Toggle Text
CyclingA change of case, letter by letter
Shimmering Text
DecorativeLight through a status while it works