SplitText
Quick Start
Trial URL
SplitText is a Club GSAP perk, join today or grab this trial URL to take it for a spin for free. Works on localhost, Codepen, CodeSandbox and Stackblitz.
gsap.registerPlugin(SplitText)
Minimal usage
var split = new SplitText("#ID", {type: "chars"});
//now animate each character into place from 100px above, fading in:
gsap.from(split.chars, {
duration: 1,
y: 100,
autoAlpha: 0,
stagger: 0.05
});
SplitText makes it easy to break apart the text in an HTML element so that each character, word, and/or line is in its own <div>
, making complex animation simple.
For example, maybe you'd like to make each character or word fade into place in a staggered fashion. SplitText automatically works around various browser inconsistencies and recognizes line breaks appropriately. Plus it is highly configurable.
Watch overview video
Features
There are a few things about SplitText that set it apart from some of the other popular libraries and plugins out there:
- Compatibility - It doesn't force non-breaking spaces into the divs like many other solutions on the web do, because those can alter the line breaks in some situations.
- Uses divs, not spans - Some browsers won't render transforms like
rotation
,scale
,skew
, etc. on<span>
s. Actually, it's related todisplay: inline
(the default for<span>
s) which is why we're using divs withdisplay: inline-block
for better animation flexibility. - Nested elements - The element you are splitting can contain nested elements such as
<span>
,<strong>
,<a>
, etc. Works for words and chars, not lines (see this workaround for lines).
read more...
- Permits
position: absolute
- This can improve performance and enable effects that would otherwise be impossible. With SplitText, you can choose if you want the divs to remain in the document flow or not. - Honors line breaks - Some other libraries force you to use a
<br>
to define line breaks, but SplitText doesn't. Of course you're welcome to use those if you prefer, but SplitText can recognize natural line breaks in the normal document flow. That's handy because you don't always know how the text will flow in every environment at various sizes. - Extremely flexible class assignment - Use no classes at all, or define a different one for characters, words, and/or lines. They don't need to be incremented (like "char1", "char2", "char3"…) but they can if you prefer (simply append
"++"
to the class name likecharsClass: "yourCharClass++"
). - Works with arrays and selectors - A single SplitText instance can manage multiple elements. You can feed in a regular array like
new SplitText([element1, element2])
. For example,new SplitText("#yourID", {wordsClass: "word"})
would find the element with the ID"yourID"
and split its text, applying a"word"
class to every resulting word. revert()
anytime - Allows you to get back to the original content (swaps in the innerHTML that was recorded when the split occurred).
Basic Usage
Start by creating a new SplitText instance and pass any of the following to the constructor to indicate which element(s) to split apart: a DOM element, an array of DOM elements, a selector object, or selector text. For example:
//a DOM element:
var yourElement = document.getElementById("yourID");
var split = new SplitText(yourElement);
//or selector text
var split = new SplitText("#yourID");
//or an array of DOM elements:
var split = new SplitText([element1, element2, element3]);
loading...
Configuration
By default, SplitText will split by characters, words, and lines which may be overkill for you. To control exactly which components are split apart (chars, words, and/or lines), or apply your own classes or set positioning to absolute
, pass a vars
configuration object as the second parameter to the constructor like new SplitText("#yourID", {type: "words,lines", wordsClass: "word++", position: "absolute"})
.
Special Properties
- String - A CSS class to apply to each character’s
, making it easy to select. If you add
"++"
to the end of the class name, SplitText will append an incremented number to each character’s, starting at 1. For example, if
charsClass
is"char++"
, the div’s class for the first character would be"char1"
, the next would be"char2"
, then"char3"
, etc. Default:undefined
. - String - A CSS class to apply to each line’s
, making it easy to select. If you add
"++"
to the end of the class name, SplitText will append an incremented number to each line’s, starting at 1. For example, if
linesClass
is"line++"
, the div’s class for the first line would be"line1"
, the next would be"line2"
, then"line3"
, etc. Default:undefined
. - Number - if you ever get odd line breaks, try increasing
lineThreshold
which is 0.2 by default which means "20% of the font-size" is where SplitText considers an element to be on a different line. In other words, it looks at the resultingelements after the split and when it comes across one that is MORE than 0.2 * font-size different on the y-axis, it assumes it's a new line. This can happen if, for example, you have a in the middle of a line that has a much bigger or smaller font size. In that case, you could set lineThreshold larger, like 0.5 (50% of the font-size would be the threshold). It's rare that this is needed. - String - If
"absolute"
, the position CSS style for all of the resultingelements will be
absolute
and theirtop
,left
,width
, andheight
CSS properties will be calculated and applied inline which can be useful for certain effects. It costs a bit more to split initially performance-wise, but it can improve performance during animation because the browser doesn’t have to do as many reflow calculations (in most cases). Keep in mind that once you split things usingposition: "absolute"
, if the containing element is resized, the split text chunks won’t reflow. Default:"relative"
. - Boolean - Collapses white space characters into one, as most browsers typically do. Set to
false
if you prefer to maintain multiple white space characters in a row. Default:true
. - [Array | Function] - Allows you to protect certain characters that are actually composed of multiple (combined) characters, like Hindi/Devanagari ones. SplitText has built-in support for emojis but it’s the same idea, where 2 or 4 characters in the string are combined to form a single one in the browser. When JavaScript splits a string into individual characters, it doesn’t recognize those combinations, thus a single emoji or Hindi character may actually, when split like
string.split("")
would have a length of 2 (or 4). So when SplitText does its magic (withoutspecialChars
), the single character would no longer show up. Instead, each of its parts would be treated as individual characters. To solve this, you can pass in an array of those special characters tospecialChars
. Advanced: if you want finer control, you can define a function instead of an array. As SplitText iterates through the characters, it feeds the REMAINING text to the function and then you return a number corresponding to how many characters should be grouped in that iteration. So technically you could apply whatever logic you want! So, for example, if the string is"ABCDE"
, the function would receive"ABCDE"
as the parameter and if you returned 1 or 0 or null, then it’d take"A"
as the character and the next time the function gets called, it’d receive"BCDE"
and if you return 3, it would tell SplitText to group"BCD"
as if it were a single character, so the next time the function gets called, it’d receive"E"
. Demo here. - String - by default, SplitText wraps things inelements, but you can define any tag like
tag: "span"
- String - A comma-delimited list of the split type(s) which can be any of the following:
chars
,words
, orlines
. This indicates the type of components you’d like split apart into distinctelements. For example, to split apart the characters and words (not lines), you’d use
type: "chars,words"
or to only split apart lines, you’d dotype: "lines"
. In order to avoid odd line breaks, it is best to not split by chars alone (always include words or lines too if you’re splitting by characters). Note: Spaces are not considered characters. Default:"chars,words,lines"
. - String - Normally words are split at every space character. The
wordDelimiter
property allows you to specify your own delimiter. If you want to split a hashtag like #IReallyLoveGSAP into words you could format the text like: #IReallyLoveGSAP and set `wordDelimiter:”“in the SplitText
config` object. - String - A CSS class to apply to each word’s
, making it easy to select. If you add
"++"
to the end of the class name, SplitText will append an incremented number to each word’s, starting at 1. For example, if
wordsClass
is"word++"
, the div’s class for the first word would be"word1"
, the next would be"word2"
, then"word3"
, etc. Default:undefined
.
Property
Description
Then, once the SplitText has been created, you can access an array of the split-apart
elements of each type by using the SplitText's "chars"
, "words"
, and/or "lines"
properties. For example:
//create a SplitText instance for the element with ID "yourElementID" that splits apart characters, words, and lines, and uses absolute positioning:
var split = new SplitText("#yourElementID", {type: "chars,words,lines", position: "absolute"});
//now animate each character into place from 100px above, fading in:
gsap.from(split.chars, {duration: 1, y: 100, autoAlpha: 0, stagger: 0.05});
//or animate each word
gsap.from(split.words, {duration: 1, x: 200, autoAlpha: 0, ease: "elastic", stagger: 0.05});
//or animate each line
gsap.from(split.lines, {duration: 1, x: 200, autoAlpha: 0, ease: "power3", stagger: 0.05});
Nested elements and emojis
SplitText will honor nested elements such as <span>
, <strong>
, <a>
, etc. Want to have some fun with emojis? No problem: 🐳 🍔 ❤️. Watch the video below.
loading...
Custom word delimiters
Ever need to split a long string of text into words but didn't want any spaces? Custom word delimiters to the rescue! You can place any character you want to mark where words should be split and SplitText will remove them during the split. #AwesomeForLongHashTags
.
loading...
Notes & limitations
In order to maintain proper line breaks, don't just split the characters - split by words too and/or lines.
If you are using custom fonts, make sure they load BEFORE you split (otherwise all the splitting will be based on the default font which could throw off how things get aligned and sized).
Some inline CSS styles are set on the resulting div elements in order to position them correctly, so if you apply classes and don't see some styles taking effect, that could be why (the inline styles are overriding the class styles). Feel free to clear those inline styles manually or use
gsap.set([elements], {clearProps: "all"})
to clear them (of course that would affect positioning, so beware).To maximize performance, only split the components you need. Don't split characters if you don't need to.
Splitting nested elements by
"lines"
is not supported (here is a workaround).If the element uses justified text (
text-align: justify
), you must useposition: "absolute"
for the SplitText because divs that remain in the document flow cannot be justified.The element of text should be displayed exactly as you want it to be at the end of your animation before you split it. In other words, the split element should be displayed on the page (having visibility: hidden or opacity: 0 is fine) and be sized like it will be when you want the split animation to run when you call SplitText.
Some browsers (like Safari) apply custom kerning by default between letters, so when characters are split apart and put into their own divs, the spacing is slightly different. A bug has been filed with the Safari team (it's a browser issue, not SplitText) but you can typically eliminate the differences by setting these CSS properties:
font-kerning: none;-webkit-text-rendering: optimizeSpeed;text-rendering: optimizeSpeed;-webkit-transform: translateZ(0);transform: translateZ(0);
SplitText is not designed to work with SVG
<text>
nodes.
Getting odd linebreaks with nested elements?
Nested elements can produce some odd results when you split text into lines. The issue arises when a nested elements like <span>
wrap onto multiple lines. SplitText must place the entire nested elements within the line that first appears on. At times this can make it appear that lines are breaking in the wrong place.
In most cases adding display: inline-block
to the nested element will yield better results. For a detailed explanation watch the video below.
Please visit our SplitText CodePen Collection for more demos of SplitText in action.
SplitText is a Club GSAP membership benefit. You must have a valid membership to use this class without violating the terms of use. Visit the club page to sign up or get more details.
Demos
FAQs
How do I include SplitText in my project?
See the installation page for all the options (CDN, NPM, download, etc.) where there's even an interactive helper that provides the necessary code. Easy peasy. Don't forget to register SplitText like this in your project:
gsap.registerPlugin(SplitText)
Is this included in the GSAP core?
Is this only for Club GSAP members?
Yes. It's our way of saying "Thank you" to those who support our efforts. If you're not a member, what are you waiting for? Satisfaction is guaranteed or your money back. Take your animation skills to the next level. If you're already a member, you can download GSAP along with this and the other bonus plugins from your account dashboard. See the installation page for details about how to get it into your project via a <script>
tag or NPM, Yarn, etc.
Can I try SplitText out for free?
You betcha! There's a trial (but fully-functional) version of SplitText that you can use on Codepen as much as you want for free. Get the URLs here. It's a fantastic way to experiment. Note: the trial version of the plugins will only work on the CodePen domain.
It works fine during development, but suddenly stops working in the production build! What do I do?
Your build tool is probably dropping the plugin when tree shaking and you forgot to register SplitText (which protects it from tree shaking). Just register the plugin like this:
gsap.registerPlugin(SplitText)