motion-split

Splits text into words, characters, or detected lines and staggers them in on viewport entry. Fully accessible: screen readers receive the original text from a visually hidden copy.

Preview

Motion that feels alive

Import

import 'motion-components/motion-split'   // just this one
import 'motion-components'               // or the whole library

Usage

<motion-split by="words" interval="0.05">
  Animate your heading
</motion-split>

by="chars"

Split into individual characters for fine-grained stagger control.

Motion
<motion-split by="chars" interval="0.03" duration="0.5">
  Motion
</motion-split>

by="lines"

Groups words by their measured Y position to create true line-by-line reveals. Lines reflow naturally with the container width.

Craft motion that earns attention, one line at a time
<motion-split by="lines" interval="0.12" duration="0.7">
  Craft motion that earns attention, one line at a time
</motion-split>

Loop

Add loop to reveal the text, hold, hide it and reveal again. hold sets how long it stays visible, gap how long it stays hidden.

One line at a time
<motion-split by="words" interval="0.06" duration="0.6" loop hold="1.4" gap="0.5">
  One line at a time
</motion-split>

The cycle runs only while the text is on screen, and once is ignored. Add pause-on-hover to freeze it while the pointer is over the text.

Properties

Attribute Property Type Default Description
by by string 'words' 'words', 'chars', or 'lines': granularity of the split
interval interval number 0.05 Delay between each unit in seconds
duration duration number 0.6 Spring duration hint in seconds
y y number 20 Initial vertical offset in px
once once boolean true Animate only on first intersection. Ignored with loop
loop loop boolean false Reveal, hold, hide and reveal again on repeat. The cycle runs while the text is on screen
hold hold number 1.6 With loop, seconds the text stays visible before it hides
gap gap number 0.5 With loop, seconds the text stays hidden before it reveals again
pause-on-hover pauseOnHover boolean false Pause the loop while the pointer is over the text, resuming on leave

JavaScript API

Trigger the split programmatically with play() and cancel().

JavaScript API
–

Accessibility

The component keeps the original unsplit text in a visually hidden span and sets aria-hidden="true" on the split spans. Screen readers announce the full phrase, not individual letters or words. Respects prefers-reduced-motion: when enabled, content appears immediately at its final state and loop never starts.