A ripple spreads from the middle letter outward, each letter swelling and brightening as the ring passes. Each span carries its distance from the center, which sets its delay.
Also known as: center out text animation, scale wave letters, pulse ripple text.
<div class="txt-ripple-text" aria-label="Resonance"><span aria-hidden="true"><span style="--i: 0; --d: 4">R</span><span style="--i: 1; --d: 3">e</span><span style="--i: 2; --d: 2">s</span><span style="--i: 3; --d: 1">o</span><span style="--i: 4; --d: 0">n</span><span style="--i: 5; --d: 1">a</span><span style="--i: 6; --d: 2">n</span><span style="--i: 7; --d: 3">c</span><span style="--i: 8; --d: 4">e</span></span></div>
.txt-ripple-text {
--c: var(--txt-color, #3b82f6);
font-size: var(--txt-size, 32px);
font-family: system-ui, sans-serif;
font-weight: 700;
line-height: 1.2;
color: var(--c);
letter-spacing: 0.04em;}
.txt-ripple-text span span {
display: inline-block;
color: color-mix(in srgb, var(--c) 65%, transparent);
animation: txt-ripple-text-ring 2.4s ease-in-out infinite;
animation-delay: calc(var(--d) * 0.12s);
}
@keyframes txt-ripple-text-ring {
0%, 20%, 100% { transform: scale(1); color: color-mix(in srgb, var(--c) 65%, transparent); }
7% { transform: scale(1.3) translateY(-0.04em); color: var(--c); }
}
@media (prefers-reduced-motion: reduce) {
.txt-ripple-text, .txt-ripple-text *, .txt-ripple-text::before, .txt-ripple-text::after, .txt-ripple-text *::before, .txt-ripple-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.