The word cracks into seven shards that fly apart in 3D, drift, then snap back together into solid text. Each shard is a copy of the word cut out with a clip-path polygon and moved with translate3d.
Also known as: text shatter css, breaking text animation, text explode and reassemble.
<div class="txt-shattering-text"><span class="txt-shattering-text-word">BREAK</span><span class="txt-shattering-text-shards" aria-hidden="true"><span style="--x: -0.8em; --y: -0.55em; --z: 0.6em; --r: -24deg; --t: 40deg; clip-path: polygon(52% 48%, 0 0, 35% 0)">BREAK</span><span style="--x: 0.1em; --y: -0.7em; --z: -0.5em; --r: 14deg; --t: -50deg; clip-path: polygon(52% 48%, 35% 0, 70% 0)">BREAK</span><span style="--x: 0.9em; --y: -0.45em; --z: 0.4em; --r: 26deg; --t: 35deg; clip-path: polygon(52% 48%, 70% 0, 100% 0, 100% 60%)">BREAK</span><span style="--x: 0.85em; --y: 0.5em; --z: -0.4em; --r: -20deg; --t: -45deg; clip-path: polygon(52% 48%, 100% 60%, 100% 100%, 60% 100%)">BREAK</span><span style="--x: 0em; --y: 0.65em; --z: 0.7em; --r: 16deg; --t: 55deg; clip-path: polygon(52% 48%, 60% 100%, 25% 100%)">BREAK</span><span style="--x: -0.85em; --y: 0.45em; --z: -0.3em; --r: 28deg; --t: -35deg; clip-path: polygon(52% 48%, 25% 100%, 0 100%, 0 50%)">BREAK</span><span style="--x: -1em; --y: -0.05em; --z: 0.3em; --r: -12deg; --t: 45deg; clip-path: polygon(52% 48%, 0 50%, 0 0)">BREAK</span></span></div>
.txt-shattering-text {
--c: var(--txt-color, #3b82f6);
font-size: calc(var(--txt-size, 32px) * 1.7);
font-family: system-ui, sans-serif;
font-weight: 900;
line-height: 1.2;
display: inline-grid;
perspective: 8em;
color: var(--c);
letter-spacing: 0.02em;}
.txt-shattering-text-word,
.txt-shattering-text-shards {
grid-area: 1 / 1;
}
/* the solid word hides the hairline seams while the shards are together */
.txt-shattering-text-word {
animation: txt-shattering-text-solid 3.6s infinite;
}
.txt-shattering-text-shards {
display: grid;
transform-style: preserve-3d;
}
.txt-shattering-text-shards span {
grid-area: 1 / 1;
animation: txt-shattering-text-fly 3.6s infinite;
}
/* a tremor first, then the solid word hands over to the shards */
@keyframes txt-shattering-text-solid {
0%, 22%, 80%, 100% { opacity: 1; transform: none; }
24% { transform: translateX(-0.03em); }
26% { transform: translateX(0.03em); }
28% { transform: translateX(-0.02em); }
30% { opacity: 1; transform: none; }
30.5%, 79% { opacity: 0; }
}
@keyframes txt-shattering-text-fly {
0%, 30% { transform: none; animation-timing-function: cubic-bezier(0.1, 0.8, 0.3, 1); }
40% { transform: translate3d(var(--x), var(--y), var(--z)) rotateX(var(--t)) rotate(var(--r)); animation-timing-function: linear; }
60% { transform: translate3d(calc(var(--x) * 1.15), calc(var(--y) * 1.15), var(--z)) rotateX(calc(var(--t) * 1.2)) rotate(calc(var(--r) * 1.2)); animation-timing-function: cubic-bezier(0.6, 0, 0.3, 1.1); }
80%, 100% { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
.txt-shattering-text, .txt-shattering-text *, .txt-shattering-text::before, .txt-shattering-text::after, .txt-shattering-text *::before, .txt-shattering-text *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--txt-color on the element or a parent.
Currently previewing #3b82f6.--txt-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 40px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.