shadcn.io is an independent project built on shadcn/ui
Text
ProShatter Text for Svelte
Click and the text shatters like glass; click again and it springs back together. For Svelte with Ark UI, when a headline should break on impact.
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
<script lang="ts">
import { ShatterText } from "@/components/ui/shatter-text";
</script>
<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"
class?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).





