← All recipes
text-reveal
Masked word reveal
Headline words rise out of their own masked line boxes, staggered — typographic motion instead of the default fade-up on everything.
All modern browsers (IntersectionObserver + CSS transforms).
Use it for
- The one hero headline, or a single section title per page
- Editorial or product-launch pages where the words are the hero
Don't — this is how it turns into slop
- Every heading and paragraph on the page — motion everywhere is noise
- Body copy or anything longer than ~12 words
Accessibility
- Screen readers get the full heading via aria-label; the split words are aria-hidden
- prefers-reduced-motion shows the text immediately, and text stays visible without JS
Performance
- Only transform animates, so it stays on the compositor
- The observer disconnects after the first reveal
The code
/* Masked word reveal — each word rises out of its own line box.
Reads as "typeset", unlike the default fade-up-everything. */
.reveal {
--reveal-duration: 0.9s;
--reveal-stagger: 70ms;
}
.reveal .reveal-word {
display: inline-block;
overflow: hidden;
/* Room for descenders so g/j/y aren't clipped by the mask. */
padding-bottom: 0.12em;
margin-bottom: -0.12em;
vertical-align: top;
}
.reveal .reveal-inner {
display: inline-block;
transform: translateY(110%);
transition: transform var(--reveal-duration) cubic-bezier(0.2, 0.7, 0.1, 1);
transition-delay: calc(var(--i, 0) * var(--reveal-stagger));
}
.reveal.is-revealed .reveal-inner {
transform: translateY(0);
}
/* No JS or reduced motion: just show the text. */
.reveal:not(.reveal--ready) .reveal-inner {
transform: none;
}
@media (prefers-reduced-motion: reduce) {
.reveal .reveal-inner {
transform: none;
transition: none;
}
}Which of these fit your site?
Scan your URL for free. The full review picks recipes for each section and hands your AI a complete design kit.
Check my site ↑