Loading skill
Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create masked staggered word reveals on scroll with GSAP ScrollTrigger. Use when headings, hero copy, section titles, or editorial text should reveal word-by-word through an overflow mask as they enter the viewport.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 4% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 14% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 17% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 17% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 48% | 0% |
82% of the viewport.0.7s to 0.9s.0.025s to 0.045s per word.yPercent: 110 to 0.power3.out or expo.out.html<h1 class="masked-reveal" data-masked-reveal> Design systems that feel alive from the first scroll. </h1>
css.masked-reveal { visibility: visible; } html.js .masked-reveal[data-masked-reveal] { visibility: hidden; } html.js .masked-reveal.is-split { visibility: visible; } .masked-reveal .word-mask { display: inline-block; overflow: hidden; vertical-align: top; } .masked-reveal .word { display: inline-block; transform: translateY(110%); will-change: transform; } @media (prefers-reduced-motion: reduce) { html.js .masked-reveal[data-masked-reveal] { visibility: visible; } .masked-reveal .word { transform: none; } }
This helper avoids the paid SplitText plugin and keeps spaces intact.
jsdocument.documentElement.classList.add("js"); gsap.registerPlugin(ScrollTrigger); function escapeHTML(value) { return value .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function splitMaskedReveal(element) { if (element.dataset.maskedRevealReady === "true") return; const text = element.textContent.trim(); element.setAttribute("aria-label", text); element.innerHTML = text .split(/(\s+)/) .map((part) => { if (!part.trim()) return part; return `<span class="word-mask" aria-hidden="true"><span class="word">${escapeHTML(part)}</span></span>`; }) .join(""); element.dataset.maskedRevealReady = "true"; element.classList.add("is-split"); } function initMaskedReveals(selector = "[data-masked-reveal]") { if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; document.querySelectorAll(selector).forEach((element) => { splitMaskedReveal(element); const words = element.querySelectorAll(".word"); gsap.set(element, { autoAlpha: 1 }); gsap.fromTo( words, { yPercent: 110 }, { yPercent: 0, duration: 0.8, ease: "power3.out", stagger: 0.035, scrollTrigger: { trigger: element, start: "top 82%", once: true, }, } ); }); } initMaskedReveals();
jsuseLayoutEffect(() => { const ctx = gsap.context(() => { initMaskedReveals("[data-masked-reveal]"); }, rootRef); return () => ctx.revert(); }, []);
ScrollTrigger.refresh() after late-loading images or layout shifts.autoAlpha: 1.aria-label.Other measured skills in the registry, with their headline benchmark lift.