Each letter traces its own outline in turn and inks in once it is drawn, like a word being lettered by hand. SVG tspans share one dash keyframe; the --i index staggers both the line and the fill.
Also known as: svg handwriting animation, sequential letter drawing, draw text one letter at a time.
<svg class="txt-letter-by-letter-stroke-draw" viewBox="0 0 400 110" role="img" aria-label="Hello"><text x="200" y="82" text-anchor="middle" font-size="96"><tspan style="--i: 0">H</tspan><tspan style="--i: 1">e</tspan><tspan style="--i: 2">l</tspan><tspan style="--i: 3">l</tspan><tspan style="--i: 4">o</tspan></text></svg>
.txt-letter-by-letter-stroke-draw {
--c: var(--txt-color, #3b82f6);
font-size: var(--txt-size, 32px);
font-family: system-ui, sans-serif;
font-weight: 700;
line-height: 1.2;
width: 8em;
height: auto;
overflow: visible;}
.txt-letter-by-letter-stroke-draw text {
font-family: Georgia, "Times New Roman", serif;
font-style: italic;
font-weight: 700;
fill: var(--c);
fill-opacity: 0;
stroke: var(--c);
stroke-width: 1.6;
stroke-linejoin: round;
stroke-dasharray: 600;
stroke-dashoffset: 600;
}
.txt-letter-by-letter-stroke-draw tspan {
animation:
txt-letter-by-letter-stroke-draw-line 0.8s ease-in-out forwards,
txt-letter-by-letter-stroke-draw-ink 0.45s ease-out forwards;
animation-delay: calc(0.2s + var(--i) * 0.25s), calc(0.8s + var(--i) * 0.25s);
}
@keyframes txt-letter-by-letter-stroke-draw-line {
to { stroke-dashoffset: 0; }
}
@keyframes txt-letter-by-letter-stroke-draw-ink {
to { fill-opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
.txt-letter-by-letter-stroke-draw, .txt-letter-by-letter-stroke-draw *, .txt-letter-by-letter-stroke-draw::before, .txt-letter-by-letter-stroke-draw::after, .txt-letter-by-letter-stroke-draw *::before, .txt-letter-by-letter-stroke-draw *::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.