shadcn.io is not affiliated with official shadcn/ui
Shatter Text breaks like glass. Click it and every character cracks into five sharp pieces that fly apart, turning and fading, and hang there in the air; click again and they spring back together into the text, overshooting a hair before they settle.
Use it for a 404 page, an easter egg, a "do not press" moment or a word that should feel fragile. For letters that fall and pile up instead, use Gravity Text; for a digital glitch, Glitch Text. At rest each character is itself, whole; shattered, it's five copies, each clipped to a wedge, and CSS transitions the install adds to your stylesheet carry them out to places worked out from the character's place in the text, then back on a spring: no animation library and no frame loop. With reduced motion the pieces don't fly: the text just cracks, and mends.
Installation
Usage
import { ShatterText } from "@/components/ui/shatter-text";<h1>
<ShatterText text="Shatter" />
</h1>Demos
Intensity
intensity is how far the pieces fly: subtle keeps them close around the word, strong scatters them wide. Click each to see. duration is the flight apart, 700 ms by default; coming back together takes a fifth longer.
Controlled
shattered holds the state yourself: here a button beside the text breaks it and mends it. trigger="manual" leaves the text itself unclickable, for text inside your own button or link, and onShatteredChange reports each change a click makes.
Accessibility
Screen readers always hear the text whole: the pieces are hidden from them, and the text is read once, as the name of a real button laid over it, with aria-pressed saying whether it's shattered. Tab reaches it, and Enter or Space shatters it or mends it, like a click. With trigger="manual" there's no button, just the text, read once. With reduced motion nothing flies: the pieces sit a hair apart, a cracked word, and mend at once.
- Tab
- Move focus to the text.
- Enter
- Shatter the text, or put it back together.
- Space
- Shatter the text, or put it back together.
FAQ
How is a character cut into pieces?
Each character has five copies of itself, each clipped with clip-path to a wedge from a point a little below its middle, cut past its box so no stroke is lost. At rest only one whole copy shows, so no seams run through the text; the pieces take over the moment it shatters and hand back once they've landed.
Is the pattern random?
It looks random but isn't: where every piece flies, how far it turns and how faint it gets come from its character's place in the text by a small formula, so the pattern is the same on every load and on the server, and different for every letter.
Can I shatter a whole paragraph?
It's made for a headline or a short label: every character is six elements, so a long paragraph means a lot of pieces. Shatter the line that matters and leave the rest still.
Can I use it inside a button?
Yes, with trigger="manual", which renders no button of its own, and shattered driven by your button. Keep the label readable for whoever presses it next, for example by mending it after a moment.
API Reference
ShatterText
<span> data-slot="shatter-text"
shattered?boolean
Whether the text lies in pieces, to hold that state yourself.
defaultShattered?boolean
Whether it starts shattered, when it keeps its own state. @default false.
- Default
false
onShatteredChange?(shattered: boolean) → void
Called with the new state each time it shatters or comes back together.
- Parameters
shattered– boolean- Returns
void
textstring
The text.
duration?number
How long the pieces take to fly apart, in milliseconds; coming back together takes a little longer.
- Default
700
intensity?"subtle" | "medium" | "strong"
How far the pieces fly. @default "medium".
- Type
"subtle" | "medium" | "strong"
trigger?"click" | "manual"
What shatters it: a click on it (a real button, which puts it back
together too), or only shattered, for text inside your own button or
link.
- Type
"click" | "manual"- Default
"click"
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-state?string
"shattered" when shown is true, otherwise "whole".
--shatter-text-durationstring
The pieces' flight apart (700ms; coming back takes a fifth longer).
--shatter-text-spreadstring
How far the pieces fly, as a share of their reach (1).
Related
- Pro
Stamp Text
EntranceLetters that land with a snap
- Pro
Pop Text
EntranceLetters that spring in with a burst
- Pro
Gravity Text
MotionLetters that fall and bounce on a click
- Pro
Glitch Text
DecorativeText that tears in bursts
- Pro
Pendulum Text
InteractiveLetters that swing as you pass
- Pro
Ripple Text
InteractiveA wave from where you click