npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@joinbox/splittext

v1.6.0

Published

Splits textContent of an HTML element into multiple parts

Downloads

81

Readme

SplitText

Splits 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 with wrapLine 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).

VERY Important

  • splitText does – due to the way browsers hyphenate text – not work with hyphens. To prevent layout shifts and wrong hyphenation, use the CSS instruction hyphens: none for all elements that you apply splitText to.
  • In order for 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" below).
  • In order to prevent words from breaking at random characters at the end of a container, apply display: inline-block on all words.
  • In order to apply CSS transform instructions to an element, use display: inline-block on the affected elements (transform does not work on display: inline).
  • Do not use display: inline-block on lines: If a paragraph contains a <br/>, it would be ignored as inline-blocks are placed next to each other.

Example

<div class="split-me">This is Content.</div>
import splitText from '@joinbox/splittext';
const restore = splitText({
    element: document.querySelector('div'),
    // Pass a custom wrapper function
    wrapLetter: (content, index) => `<div class='my-letter' style='--splitTextIndex: ${index}'>${content}</div>`,
    // 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();
.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 <br/>s within a line */
    display: block;
}
.word {
    /* Allows you to use transform on a word and prevents wrong line breaks */
    display: inline-block;
}

Usage

Arguments

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.

Return Value

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 <a> 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 <div>reference</div> is split, the content of the div will always be reference (and not ref-erence or refer-ence) – no matter how we read it. The div will stretch over two lines, but as its top is on the upper line, the whole word will be attributted to the upper line. The line will therefore become too long and in the worst case mess up your layout.