Split Text Component

Splits a line of text into characters, words, or lines and reveals the pieces with a staggered animation — on mount or when it scrolls into view. Built on GSAP's SplitText and ScrollTrigger for accurate masking and resize-safe line splitting.

Features

  • Split by chars, words, or lines, each masked so pieces reveal from behind an edge.
  • Play on mount or on scroll into view via scrollTrigger with a configurable start.
  • Fully overridable motion through animationProps (GSAP tween vars).
  • autoSplit re-splits on resize so line breaks stay correct.
  • Respects prefers-reduced-motion — shows the final text with no animation.

Text that reveals itself, one word at a time.

Playground

Change what the text splits into and tune the motion, then replay.

Split and reveal your text with GSAP.

Controls
Controls

Installation

Usage

Notes & caveats

  • Wrap your text in a single element. children must be one element (e.g. an <h2> or <p>) — the component splits its first child. A raw string or multiple siblings won't animate (a dev-only warning is logged).
  • lines needs a block element with a width. Line splitting is only meaningful when the text wraps, so give the wrapper a width (e.g. max-w-md); on an inline or shrink-wrapped element every "line" collapses into one.
  • chars is best for short, Latin text. Character splitting breaks emoji and complex scripts (Arabic, Indic, ligatures), and on long text the stagger × count total gets very long. Prefer words or lines there.
  • Font loading is handled for you. The split waits for document.fonts.ready, so line breaks and masks measure against the real font — no need to enable autoSplit just for that.
  • Reduced motion. With prefers-reduced-motion, the text is shown immediately with no animation.

Props

PropertyTypeDefaultDescription
childrenReactNoderequiredA single text element (e.g. a heading or paragraph) to split and animate.
classNamestringAdditional CSS classes for the wrapper.
variantSplitUnit"words"Which unit the text is split into and animated.
maskbooleantrueMask each split piece (clip it) so it reveals from behind an edge instead of animating in fully visible. Masks by the same unit set in `variant`.
animationPropsgsap.TweenVars{ yPercent: 120, rotate: 5, stagger: 0.2, duration: 0.4 }GSAP tween vars merged over the defaults, e.g. `{ duration: 1.2 }`.
scrollTriggerbooleanfalsePlay the animation when the element scrolls into view instead of on mount.
startstring"top 85%"ScrollTrigger start position (only used when `scrollTrigger` is true).
autoSplitbooleanfalseRe-split on resize so line breaks stay correct. Note: this replays the animation on every resize, so it suits looping reveals more than one-shot entrances. Font-load correctness is handled automatically either way.
markersbooleanfalseShow ScrollTrigger debug markers.