SplitText (React)
React wrapper for splitText() with lifecycle handling and viewport callbacks.
SplitText is available in two React entry points:
griffo/react(this page) — imperative callbacks for full control over animations.griffo/motion— declarative Motion-powered animations. See the Motion API.
For text morphing between changing strings, see MorphText (griffo/morph).
Props
Common wrapper DOM props (id, role, tabIndex, aria-*, data-*, and handlers like onClick) are forwarded to the wrapper.
SplitTextOptions
Callback Signature
All callbacks receive the same result object:
interface SplitTextElements {
chars: HTMLSpanElement[];
words: HTMLSpanElement[];
lines: HTMLSpanElement[];
revert: () => void;
}Callback props can return animations/promises:
type CallbackReturn =
| void
| { finished: Promise<unknown> }
| Array<{ finished: Promise<unknown> }>
| Promise<unknown>;onRevert is a separate zero-argument callback that fires when a split cycle actually reverts.
With autoSplit + lines, reattach scroll/timeline logic in onResplit so it uses the new split elements.
Font Loading
React and Motion components wait for document.fonts.ready by default (waitForFonts={true}) for stable kerning.
If you need immediate splitting, opt out:
For vanilla JavaScript usage, see the vanilla API docs.
Accessibility
Griffo handles accessibility automatically. For elements that support aria-label (headings, landmarks), it labels the parent. For generic elements (<span>, <div>, <p>) and nested inline content, it keeps a screen-reader-only copy and hides visual split nodes from assistive tech. Existing aria-label values are preserved.
See the vanilla API docs for details.
Motion Component
The Motion component (griffo/motion) adds declarative animation props — initial, animate, whileInView, whileScroll, whileHover, and more — powered by Motion. It requires the motion package.
See the Motion API for the full reference, supported shapes, and trigger priority rules.
Morph Component
The Morph component (griffo/morph) is a dedicated API for text morphing between string updates with persistent character identity and built-in enter/exit transitions.
Examples
Basic
Wrap any element with SplitText and animate in onSplit.
Viewport Detection
Use viewport for scroll-triggered animations. Set the start state with initialStyles, and enable resetOnViewportLeave for repeat animations. By default, reset happens when the element is fully out of view; set viewport.leave to trigger sooner.
For one-time animations, use once: true in the viewport options:
Viewport Options
Usage tip: To run leave callbacks at the same threshold as enter, set viewport.leave to match viewport.amount and animate in onViewportLeave. Keep resetOnViewportLeave for instant resets once fully out of view.
Initial Styles
Use initialStyles to define start states declaratively, without setup loops in onSplit.
Style values support normal CSS values and CSS custom properties.
You can also use a function for per-element customization:
Auto-Revert
Enable revertOnComplete and return an animation from the callback. Griffo restores original HTML when it finishes. Use onRevert to run follow-up logic.
Masked Reveal
Use mask to wrap elements in a clipping container for reveal animations.
Nested HTML Elements
Griffo preserves inline elements like <a>, <em>, and <strong>, including attributes (href, class, data-*, etc.).
Authored hard breaks are preserved automatically. Explicit <br> and block-level descendants are treated as hard boundaries; when splitting chars/words, boundaries are normalized to <br> in the split output.
With Ref (Scroll-Driven)
Pass a ref to SplitText to connect scroll-driven animations with Motion's scroll(). The ref points to the wrapper element.
For practical usage patterns, see the React examples.