SplitText

SplitText is a powerful feature that allows you to animate individual characters, words, or lines of text using the GSAP SplitText plugin.

See in Action

Introduction

The .splitText modifier automatically divides the element's text into separate elements that can be animated individually. This enables the creation of sophisticated animation effects like text appearing letter by letter, word by word, or line by line.


Split Types

Choose one split type per element. Multiple types cannot be combined.

.chars - Characters (Default)

Splits text into individual characters:

<h1 v-gsap.splitText.chars.from="{ opacity: 0, y: 20 }">
  Character by character animation
</h1>

.words - Words

Splits text into individual words:

<p v-gsap.splitText.words.whenVisible.from="{ opacity: 0, x: -30 }">
  This sentence animates word by word
</p>

.lines - Lines

Splits text into individual lines:

<div v-gsap.splitText.lines.from="{ opacity: 0, y: 50 }">
  This is a long text that spans
  across multiple lines and each line
  animates separately from the others
</div>
Note: If no split type is specified, .chars is used by default. Only one split type can be used per element.

Stagger

Automatic Stagger

SplitText works perfectly with stagger to create sequential effects:

<!-- With stagger modifier -->
<h1 v-gsap.splitText.chars.stagger.from="{ opacity: 0, y: -30 }">
  Stagger effect
</h1>

<!-- With custom stagger value -->
<p v-gsap.splitText.words.from="{ opacity: 0, x: 20, stagger: 0.1 }">
  Custom stagger
</p>

Speed Control

<!-- Fast stagger -->
<div v-gsap.splitText.chars.from="{ opacity: 0, y: 20, stagger: 0.05 }">
  Fast animation
</div>

<!-- Slow stagger -->
<div v-gsap.splitText.chars.from="{ opacity: 0, y: 20, stagger: 0.3 }">
  Slow animation
</div>

Masks

The .mask modifier creates masks around split elements, useful for cleaner reveal effects:

Character Masks

<h1 v-gsap.splitText.mask.chars.from="{ opacity: 0, y: 100 }">
  Text with character masks
</h1>

Word Masks

<p v-gsap.splitText.mask.words.whenVisible.from="{ y: '100%' }">
  Reveal effect for words
</p>

Line Masks

<div v-gsap.splitText.mask.lines.from="{ y: '100%', stagger: 0.1 }">
  Each line appears from below
  with a very elegant
  mask effect
</div>

Advanced Examples

Typewriter Effect

<p v-gsap.splitText.chars.from="{ opacity: 0, stagger: 0.05 }">
  This text appears as if being typed
</p>

Explosion Effect

<h2 v-gsap.splitText.chars.from="{ 
  opacity: 0, 
  scale: 0, 
  rotation: 'random(-180, 180)',
  stagger: 0.02 
}">
  EXPLOSION!
</h2>

ScrollTrigger Animation

<div v-gsap.splitText.words.mask.whenVisible.from="{ 
  y: '100%', 
  stagger: 0.1,
  start: 'top 80%'
}">
  This text animates when entering the viewport
  word by word with reveal effect
</div>

Infinite Animation

<h1 v-gsap.splitText.chars.infinitely.fromTo="[
  { y: 0 },
  { y: -10, stagger: 0.1, yoyo: true, repeat: 1 }
]">
  Swaying text
</h1>

Options

You can pass SplitText-specific options using the splitText key inside the directive value. New options added in this version:

  • splitText.waitForFonts (default: true)
    • Ensures accurate measurements when using custom web fonts. The directive performs an immediate split so you can target elements right away, then waits for document.fonts.ready and re-splits for final sizing. Set to false to disable waiting.
    • Example:
    <h1 v-gsap.splitText.chars.from="{ opacity: 0, y: 20, splitText: { waitForFonts: true } }">
      Smooth with custom fonts
    </h1>
    
  • splitText.onSplit
    • Callback fired after each split or re-split. Receives an object { el, split } where split is the SplitText instance.
    • Example:
    <h2 v-gsap.splitText.words.from="{
      opacity: 0,
      y: 24,
      splitText: {
        onSplit: ({ el, split }) => {
          // Access split.words / split.chars / split.lines
          console.log('Split ready', el, split)
        }
      }
    }">
      Inspect words after split
    </h2>
    

Custom Event

  • In addition to the onSplit callback, the element dispatches a DOM event 'vgsap:split' with detail { el, split }. This allows using addEventListener without inline callbacks.
    el.addEventListener('vgsap:split', (e) => {
      const { el, split } = e.detail
      // do something
    })
    

Notes

  • When using .mask, the plugin adds wrapper elements to achieve reveal effects; animations still target the split elements (chars/words/lines), not the masks.
  • If you use .stagger with .splitText, a default stagger of 0.1 is applied unless you explicitly set stagger: false or 0.

Technical Considerations

Performance

  • SplitText creates additional DOM elements, so use sparingly on very long texts
  • Split elements are automatically cleaned up when the component is unmounted
  • Masks add additional DOM elements but provide cleaner effects

Responsive Design

SplitText automatically adapts to text size changes, but for fully responsive layouts consider using .mobile and .desktop modifiers:

<h1 
  v-gsap.splitText.chars.desktop.from="{ opacity: 0, y: 20, stagger: 0.05 }"
  v-gsap.splitText.words.mobile.from="{ opacity: 0, x: -20, stagger: 0.1 }"
>
  Different behavior on mobile and desktop
</h1>

Timeline Integration

SplitText works perfectly within timelines:

<div v-gsap.timeline.whenVisible class="container">
  <h1 v-gsap.add.splitText.chars.from="{ opacity: 0, y: -20, stagger: 0.05 }">
    Main title
  </h1>
  <p v-gsap.add.splitText.words.from="{ opacity: 0, x: -30, stagger: 0.1 }">
    Subtitle that follows
  </p>
</div>
Note: Each element in a timeline can use a different split type, but each individual element can only use one split type.

Advanced Options

Custom Split Configuration

You can pass additional options for SplitText configuration using the splitText property in the value object:

<div v-gsap.splitText.chars.from="{
  opacity: 0,
  y: 20,
  stagger: 0.1,
  splitText: {
    reduceWhiteSpace: true,
    wordDelimiter: ' ',
    charsClass: 'char',
    wordsClass: 'word',
    linesClass: 'line'
  }
}">
  Text with custom configuration
</div>

Available SplitText Options

The splitText object supports all GSAP SplitText configuration options:

  • reduceWhiteSpace: Boolean to reduce white space
  • wordDelimiter: Custom word delimiter (default: space)
  • charsClass: CSS class for character elements
  • wordsClass: CSS class for word elements
  • linesClass: CSS class for line elements
  • tag: HTML tag for split elements (default: 'div')
  • And all other GSAP SplitText options
<!-- Example with multiple custom options -->
<h1 v-gsap.splitText.words.from="{
  opacity: 0,
  x: -50,
  stagger: 0.15,
  splitText: {
    reduceWhiteSpace: true,
    wordsClass: 'split-word',
    tag: 'span'
  }
}">
  Advanced Configuration Example
</h1>

Complex Animations

<h1 v-gsap.splitText.chars.fromTo="[
  { 
    opacity: 0, 
    scale: 0.5, 
    rotation: -90 
  },
  { 
    opacity: 1, 
    scale: 1, 
    rotation: 0, 
    stagger: 0.08,
    ease: 'back.out(1.7)'
  }
]">
  Complex animation
</h1>

Note: SplitText is included for free in GSAP since version 3.13.0. No Club membership required for production use.
Warning: Elements with SplitText are modified in the DOM. Avoid directly manipulating the text content of these elements after initialization.