SplitText
SplitText is a powerful feature that allows you to animate individual characters, words, or lines of text using the GSAP SplitText plugin.
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>
.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>
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 spacewordDelimiter: Custom word delimiter (default: space)charsClass: CSS class for character elementswordsClass: CSS class for word elementslinesClass: CSS class for line elementstag: 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>