April 27, 2026IntermediateText Effects
Text Reveal System
GSAP SplitText-based text reveal system. Text elements opt in with data-reveal-01 and split into lines, words, or characters. Supports load-time reveals, scroll-triggered reveals, scrubbed scroll reveals, and manual split-only mode for custom timelines. Per-element overrides for duration, stagger, delay, ease, and replay behavior.
Preview
We create motion-forward digital experiences
No-5 Studio is a motion-forward design studio. We build websites that communicate confidence, craft, and intention through every interaction.
Source
import TextRevealSystem from "./index.jsx";
import styles from "./demo.module.css";
const ITEMS_LOAD = [
{
as: "h1",
text: "We create motion-forward digital experiences",
splitType: "lines",
className: styles.heading,
},
{
as: "p",
text: "No-5 Studio is a motion-forward design studio. We build websites that communicate confidence, craft, and intention through every interaction.",
splitType: "words",
delay: 0.3,
},
];
const ITEMS_SCROLL = [
{
as: "h2",
text: "Scroll-triggered line reveal",
splitType: "lines",
scroll: true,
className: styles.heading,
},
{
as: "p",
text: "This paragraph reveals word by word as it enters the viewport. The animation plays once by default.",
splitType: "words",
scroll: true,
},
];
const ITEMS_CHARS = [
{
as: "h2",
text: "Character reveal on scroll",
splitType: "chars",
scroll: true,
className: styles.heading,
},
{
as: "p",
text: "Each letter animates individually with a tight stagger for a typewriter-like entrance.",
splitType: "chars",
scroll: true,
},
];
const ITEMS_SCRUB = [
{
as: "h2",
text: "Scrubbed scroll reveal",
splitType: "words",
scroll: "scrub",
className: styles.heading,
},
{
as: "p",
text: "This text follows the scroll position — scrub forward to reveal, scrub back to hide.",
splitType: "words",
scroll: "scrub",
},
];
export default function TextRevealSystemDemo() {
return (
<div>
{/* Hero — load-time reveal */}
<section className={styles.section} data-bg="dark">
<p className={styles.label}>Load reveal</p>
<TextRevealSystem items={ITEMS_LOAD} />
</section>
{/* Scroll-triggered reveal */}
<section className={styles.section}>
<p className={styles.label}>Scroll trigger</p>
<TextRevealSystem items={ITEMS_SCROLL} />
</section>
{/* Character reveal */}
<section className={styles.section} data-bg="dark">
<p className={styles.label}>Characters</p>
<TextRevealSystem items={ITEMS_CHARS} />
</section>
{/* Scrubbed reveal */}
<section className={styles.section}>
<p className={styles.label}>Scrub</p>
<TextRevealSystem items={ITEMS_SCRUB} />
</section>
<div className={styles.spacer} />
</div>
);
}
Dependencies
gsap