Motion · GSAP-style

Split text

$.splitText('h1', { type: 'words,chars' }) wraps every word and letter so you can stagger them — and revert() puts the original markup back.

Accessible by default

Splitting text into hundreds of spans would make a screen reader spell words out letter by letter. The add-on sets aria-label on the element to the original text and hides the pieces with aria-hidden, so assistive technology still reads one sentence.

type is any of lines, words, chars. mask: 'lines' (or 'words') wraps each piece in an overflow-clipped box, so text can slide up from behind an invisible edge. Nested markup like <b> and links is preserved.

Live · Animate a headline by characters, words or lines

Write less, ship more, keep the web fast.

View the source for this demo
HTML
<p id="sp-head" class="sp-head">Write less, <em>ship more</em>, keep the web fast.</p>
<div class="row">
  <button type="button" data-split="chars">By characters</button>
  <button type="button" data-split="words">By words</button>
  <button type="button" data-split="lines">By lines</button>
</div>
<pre class="out" id="sp-out"></pre>
JavaScript
let split = null;
$('[data-split]').on('click', async function () {
  const type = this.dataset.split;
  if (split) split.revert();
  split = $.splitText('#sp-head', { type: type === 'chars' ? 'words,chars' : type, mask: type === 'chars' ? 'words' : type });
  const parts = split[type];
  $('#sp-out').text(parts.length + ' ' + type + " — $.from(split." + type + ", { yPercent: 110, stagger: " + (type === 'chars' ? 0.02 : 0.08) + ' })');
  await $.from(parts, { yPercent: 110, opacity: 0, duration: 0.6, ease: 'power3.out', stagger: type === 'chars' ? 0.02 : 0.08 });
});

More examples

Scroll-triggered heading reveal (with the scroll add-on)

JavaScript
$('h2.reveal').each(function () {
  const split = $.splitText(this, { type: 'lines', mask: 'lines' });
  $.from(split.lines, { yPercent: 100, stagger: .1, duration: .7, ease: 'power3.out',
    scrollTrigger: { trigger: this, start: 'top 85%' } });
});

API

$.splitText(target, { type: "lines,words,chars", mask, aria, autoSplit, onSplit }) → { lines, words, chars, revert() }

Split text for animation, accessibly.

Reference: jskjs.split.js →
stagger: 0.1 · { each | amount, from: "center" | "end" | "edges" | "random" | index | [x, y], grid: [rows, cols] | "auto", axis, ease }

Offset each target's start.

Reference: stagger →

Migrating

Coming from GSAPnew SplitText(el, { type }) → $.splitText(el, { type }), with the same chars, words, lines arrays and revert().

Related features