Splits textContent of an HTML element into multiple parts
npm install @joinbox/splittextSplits textContent of an HTML element into multiple parts for
- letters
- words
- lines
Supports:
- custom functions that wrap the parts into any text provided
- indices on all types of parts (letters, words and lines)
- restoring to original content
- restore on resize and updated split after a certain debounce
- content that contains nested elements (see "Background" below); in order for them to work withwrapLine make sure that they are display: inline-block
By default, all types are wrapped into a span with class letter, word or line and an
attribute data-letter-index, data-word-index or data-line-index with the corresponding
index that counts up (per HTML element).
splitText does – due to the way browsers hyphenate text – not work with hyphens. To preventhyphens: none for all elements splitText to.wrapLine to work, you may not use false as the value for wrapWord; in other words, every word must be wrapped for wrapLine to work (see "Background"display: inline-block on all words.transform instructions to an element, use display: inline-block on thetransform does not work on display: inline).display: inline-block on lines: If a paragraph contains a
, it would be``html`This is Content.
`javascript
import splitText from '@joinbox/splittext';
const restore = splitText({
element: document.querySelector('div'),
// Pass a custom wrapper function
wrapLetter: (content, index) =>
,
// Don't wrap lines; if you wrap lines, you must also wrap words
wrapLine: false,
// Prevent restore and update on resize
updateOnResize: false,
});
// Restore content of div to original content; this destroys the elements created by splitText.
restore();
``css
.split-me {
/ Don't hyphenate text; we cannot query browser-added hyphens through JS /
hyphens: none;
}
.my-letter {
/ Allows you to use transform on a letter /
display: inline-block;
}
/ Line is not used in the example above; this is for documentation purposes only /
.line {
/ Do not use inline-block for lines as it will swallow
s within a line /
display: block;
}
.word {
/ Allows you to use transform on a word and prevents wrong line breaks /
display: inline-block;
}
`
Usage
$3
Pass arguments as an object. The following properties are supported:
- element (required): the HTML element whose textContent will be split and wrapped
- wrapLetter, wrapWord and wrapLine:
- either false if parts should not be wrapped at this level
- or a function that takes two arguments content and index and is expected to return a
string. Defaults to a function (see above).
- updateOnResize: boolean (true updates on x and y axis changes, false does never update) or
the axis or axes that should trigger the update, i.e. ['x'], ['y'] or ['x', 'y']. Why?
Because mobile browsers often change the viewport height when scrolling (because the show or
hide the address bar) which causes splitText to update unnecessarily.$3
Returns a function that, when called, destroys all elements created by splitText. Try to use it
as soon as the animations splitText was used for is done to ensure the text is as responsive
as possible again.
Background
- Splitting into lines fails when a (child) element stretches over more than one line (e.g.
a long element): We would have to split that (child) element into multiple elements,
one per line that the child element occupies which would get (very) messy.
- Why do we have to use wrapWord in order for wrapLine to work? When wrapping lines, we
go through all child elements and compare their vertical position
in the rendered document; once the vertical position changes, a new line is assumed. If there
are no children within the element, we can't go through them; and if you wrap only letters, a
line break may happen after every letter.
- Why must we remove all hyphenation from texts that are split? If the browser hyphenates a
multiline text, it does not add the hyphens to the DOM; they can therefore not be read by
JavaScript – because they're just not there. If is split, the content of the
div will always be reference (and not ref-erence or refer-ence`) – no matter how we read it.