Giter Club home page Giter Club logo

splittype's Introduction

SplitType

npm version

SplitType is a small javascript library that splits HTML text into elements so that lines, words, and characters can be animated independently. It was inspired by GSAP's SplitText plugin, and can be used with any animation library.

Under the hood, SplitType changes the html structure of the target elements, wrapping each line, word, and/or character in a element.

Features

  • Splits text into lines, words, and/or characters
  • Customizable class names for split text elements
  • Detects natural lines breaks in the text
  • Preserves explicit lines breaks (<br> tags)
  • Preserves nested HTML elements inside the target elements
  • Supports unicode symbols such as emojis

Supported Browsers

SplitType works in all modern browsers. Internet Explorer is no longer supported.

  • ✅ Chrome
  • ✅ Firefox
  • ✅ Edge
  • ✅ Safari
  • ❌ Internet Explorer

Installation

Yarn/NPM

You can install SplitType as a dependency using yarn or npm.

yarn add 'split-type'
import SplitType from 'split-type'

CDN

Or, include the following <script> tag to load SplitType from a CDN.

<!-- Minified UMD bundle -->
<script src="https://unpkg.com/split-type"></script>

Usage

Splitting Text

The SplitType class "splits" the text content of the target elements using the provided options. It returns a SplitType instance which provides access to the split text nodes. By default, text will be split into lines, words, and characters, using relative position.

Because SplitType is a class, it cannot be called without the new keyword. As an alternative, you can use the static method SplitType.create().

const text = new SplitType('#target')
// or
const text = SplitType.create('#target')

// Array of line elements
text.lines
// Array of word elements
text.words
// Array of character elements
text.chars

Important: The following style should be applied to all target elements. This prevents the characters from shifting slightly when text is split/reverted.

.target {
  font-kerning: none;
}

Also, if the target elements are inside a flex container, they need to have a defined width to prevent the text from moving when it gets split.

The types option

The types option lets you specify which units the text will be broken up into. There are three types: lines, words, and characters. You can specify any combination of these types. However, splitting text into only characters is not recommended. To maintain normal line breaks, you need to include words and/or lines.

// Splits text into lines, words, characters (default)
const text = new SplitType('#target')
// Splits text into words and characters
const text = new SplitType('#target', { types: 'words, chars' })
// Splits text into lines
const text = new SplitType('#target', { types: 'words' })

Accessing split text nodes

You can access the split lines/words/characters via properties on the SplitType instance.

// Splits text in element with ID="target"
const text = new SplitType('#target')

// An array of the all line elements
console.log(text.lines)
// An array of all word elements
console.log(text.words)
// An array of all character elements
console.log(text.chars)

You can also use selectors to access split text elements

const text = new SplitType('#target')
const words = document.querySelectorAll('#target .word')

Reverting Split Text

The revert method will restore the target element(s) to their original html content. It also removes all data associated with the target elements from SplitType's internal data store. It is recommended to revert split text once it is no longer needed (for example at the end of an animation, or before the component is unmounted).

Text can be reverted using the instance method:

instance.revert()

Or using the static method, and specify the target elements to revert.

SplitType.revert('#target')

Nested Elements

As of v0.3, nested elements inside the target elements will be preserved when text is split. This makes it possible to:

  • Apply custom styles to specific parts of the test
  • Include interactive elements such links are buttons inside split text.
<p id="target">Foo <em>Bar</em></p>
SplitType.create('#target')

Result

<div class="target">
  <div class="line" style="display: block; text-align: start; width: 100%">
    <div class="word" style="display: inline-block; position: relative">
      <div class="char" style="display: inline-block">F</div>
      <div class="char" style="display: inline-block">o</div>
      <div class="char" style="display: inline-block">o</div>
    </div>
    <em style="display: inline-block; position: relative"
      ><div class="word" style="display: inline-block; position: relative">
        <div class="char" style="display: inline-block">B</div>
        <div class="char" style="display: inline-block">a</div>
        <div class="char" style="display: inline-block">r</div>
      </div>
    </em>
  </div>
</div>

Caveat: this feature is not compatible with splitting text into lines. When split lines is enabled, if the text content of a nested element gets broken onto multiple lines, it will result in unexpected line breaks in the split text.

Absolute vs Relative position

By default, split text nodes are set to relative position and display:inline-block. SplitType also supports absolute position for split text nodes by setting { absolute: true }. When this is enabled, each line/word/character will be set to absolute position, which can improve performance for some animations.

Responsive Text

When text is split into words and characters using relative position, the text will automatically reflow when the container is resized. However, when absolute position is enabled, or text is split into lines (default), the text will not reflow naturally if the viewport is resized. In this case, you will need to re-split text after the container is resized. This can be accomplished using an event listener or ResizeObserver and calling instance.split() after the container has been resized.

For a complete example, see __stories__/components/Example.svelte

const text = new SplitType('#target')

// Reposition text after the container is resized (simplified version)
// This example uses lodash#debounce to ensure the split method only
// gets called once after the resize is complete.
const resizeObserver = new ResizeObserver(
  debounce(([entry]) => {
    // Note: you should add additional logic so the `split` method is only
    // called when the **width** of the container element has changed.
    text.split()
  }, 500)
)
resizeObserver.observe(containerElement)

API Reference

SplitType(target, [options])

target

The target element(s) for the SplitType call. This can be a selector string, a single element, or a collection of elements (ie NodeList, jQuery object, or array).

options

name type default description
absolute boolean false If true, absolute position will be used to for split text nodes.
tagName string "div" The HTML tag that will be used for split text nodes
lineClass string "line" The className all split line elements
wordClass string "word" The className for split word elements
charClass string "char" The className for split character elements
splitClass string null A className for all split text elements
types string "lines, words, chars" Comma separated list of types
split string "" Alias for types

Instance Properties

get instance.lines  :  HTMLElement[]

An array of the split line elements in the splitType instance

get instance.words  :  HTMLElement[]

An array of the split word elements in the splitType instance

get instance.chars  :  HTMLElement[]

An array of the split character elements

get instance.settings  :  SplitTypeOptions

The settings for this splitType instance.

get instance.isSplit  :  boolean

Indicates if the target elements are currently split

method instance.split(options)   => void

The split method is called automatically when a new SplitType instance is created. It can be called manually to re-split the target elements. By default it will use the same options that were passed to the constructor when the instance was created. You can also provide new options. This method is useful when you need to re-split text after the browser or container element has been re-sized.

method instance.revert()   => void

Restores the target elements to their original html content. It also removes data associated with the target elements from SplitTypes internal data store.

Static Properties

get SplitType.defaults : {SplitTypeOptions}

Gets the current default settings for all SplitType instances. The default settings can be modified using the setDefaults methods.

method SplitType.setDefaults(options: any)  => SplitTypeOptions

Sets the default options for all SplitType instances. The provided object will be merged with the existing SplitType.defaults object. Returns the new defaults object.

method SplitType.create(target, options)  => SplitType

Creates a new SplitType instance using the provided parameters. This method can be used to call SplitType without using the new keyword.

method SplitType.revert(target)  => void

Reverts the target element(s) if they are currently split. This provides a way to revert split text without a reference to the SplitType instance.

Examples

Text Animation with GSAP

// Split text into words and characters
const text = new SplitType('#target', { types: 'words, chars' })

// Animate characters into view with a stagger effect
gsap.from(text.chars, {
  opacity: 0,
  y: 20,
  duration: 0.5,
  stagger: { amount: 0.1 },
})

splittype's People

Contributors

bakura10 avatar danielkorte avatar dependabot[bot] avatar geopic avatar learyjk avatar lukepeavey avatar sntiagomoreno avatar stevenjpx2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

splittype's Issues

Feature Request: preserve HTML tags in split text

First thing first, i love this library, easy to use and understand, but my problem is, i have italic text on my div, after using split line it's just regular text without italic anymore. How do i solve this problem?

Memory Leak Issue

SplitType uses an internal data store (similar to jQuery's data method) to store arbitrary data on DOM elements.

Most of this data is temporary and gets removed at the end of the split function. However, I noticed that this is not working consistently when using SplitType in React applications. In some cases, the data store retains all of the data associated with split text nodes even after text has been reverted and those elements no longer exist. This could result is significant memory leak, as more data is accumulated with every SplitType call.

Also, a small amount of data (associated with the target elements) is currently retained even after text has been reverted. Reverting a splitType instance should remove all stored data associated with the target elements.

Split Text containing Emojis and Symbols

Description

SplitType breaks emojis when splitting text into characters

Steps to Reproduce

<p id="target">Foo😀 Bar👌</p>
const text = new SplitType('#target')

Rendered Output
screenshot

Expected Results

Splits text without breaking emojis

Typescript error on building NextJS 14 app

Hi,

I have a strange behaviour that just happened after purging my package-lock.json, node_modules folder and .next folder and gave my app a fresh npm install.

Suddenly there is an error with SplitType that was not there before.

image

The line types: 'words, chars', is stating the error
Type '"words, chars"' is not assignable to type 'TypesList | undefined'. Did you mean '"words,chars"'?

Now, when I remove the space -> types: 'words,chars' the error seems to be gone in VS Code, but as you can see in the screen that when I run npm run build the typescript error is showing up WITH a space.

I already updated and restarted VS Code, I again purged node_modules, package-lock and .next but this error keeps persisting.

So where does the space between 'words, chars' coming from, when it is not in my code any more and why is this even considered as an error in the first place when it worked all the time and even in the SplitTypes docs it is written with a space?

Option to keep certain groups of letters from splitting? (specialChars in SplitText)

If you're using ligatures and want to split by characters, an issue pops up where since each character is an individual, it won't recognise the character beside and won't be able to show in its ligature form. I've recreated the problem in a CodePen below. The solution with GSAP's SplitText plugin are prop where you can prevent certain combinations of letters from being split individually. Is there something in the Split Type library that does something similar? I couldn't find it in the docs but wondering if I've accidentally glossed over it?

Edit: Sorry forgot to post a link to the CodePen: https://codepen.io/chigggsy/pen/GRLpLRG

Announcement: dropping support for internet explorer

As of v0.3.0, we are dropping support for internet explorer.

Why

  • Microsoft officially ended support for IE on June 15 2022.
  • Most major websites and platforms have stopped supporting IE, including GitHub, Google, Facebook, etc.
  • The tools that we use for testing (Storybook, Puppeteer, Chromatic) do not support Internet Explorer.

For now, IE 11 is still included in the browser list for our babel configuration, so theoretically the library should continue to work on IE 11.

Please let me know if you have any feedback about this.

How can I wrap each generated div line with a span then revert upon finishing the animation?

I've been playing with this library today and I'm beyond impressed by how simple & reliable it is to split typographic elements! However, there are 2 things that I'm currently struggling with at the moment:

  1. How can I wrap each generated div element with a span tag? The reason for this is to re-create this scroll-triggered animation using the overflow: hidden trick --> https://codepen.io/Ahmad_Mansour/pen/rNzVYbq?editors=0010
  2. How can I revert the split lines, words & chars after executing the animation because I'm not sure how to approach that.

This is the sandbox that I re-created so you don't have to start from scratch for this particular case.
--> https://codepen.io/Ahmad_Mansour/pen/PoKNZqo?editors=0010

Thanks in advance!

SplitType not including some spaces

Hi

I'm splitting texts into words, and some spaces are lost in the process but not all. If you open the menu in https://immosolid-staging-cd58a2c892d12f4668483.webflow.io/ 'Aktuelle Angebote' has a missing space, and the smaller links ('Informationen für Eigentümer') have the first space present but the second missing. If I revert splitType, spaces come back.
For testing, I tried to split h1 on the same page and had no issue with the spaces. I animate with gsap.

Large words are not breaking

Hey,

I saw a text reveal with Split Type demo on codepen. One issue I found is words are not breaking if the last word of a sentence is larger. If you see in the demo(last example, that red one) the word "interactivity" is not breaking to next line .

https://codepen.io/designcourse/pen/vYQQKBW

How can I make it to the next line if word is bigger one?

Text Splitting Issue When Moving Page

Issue Description:
When we move a page to a new page, the text content on the page is splitting incorrectly. It appears that the old data is being splitted and displayed on the new page, This issue occurs in NextJS.

useEffect(() => {
    setTimeout(() => {
      SplitType.create("[text-split]", {
        types: "lines",
        splitClass: "line-wrapper",
        tagName: "span",
      });

      SplitType.create(".line", {
        types: "lines",
        splitClass: "line-inner",
        tagName: "span",
      });
    }, 1000);
  });

i added a timeout to ensure that the original text was correct but after running splitType it just became the old text

codesandbox
live demo

On the page click next link to move to the next page. Thank you, I hope you can help me with this issue

Not splitting lines correctly

Hi,
I'm trying to split my content into lines but it appears to be splitting my paragraph instead. Any advice greatly appreciated please.

I'm using version 0.3.3 and Next.js version 13.2.4

Here's the code I'm using to split the text:

useEffect(() => {
    if (textRef.current) {
      gsap.registerPlugin(ScrollTrigger)
      const newText = new SplitType(textRef.current, { types: 'lines, words' })

      newText.lines.forEach((target) => {
        gsap.to(target, {
          backgroundPositionX: 0,
          ease: 'none',
          scrollTrigger: {
            trigger: target,
            markers: true,
            scrub: 0.5,
            start: 'top bottom',
            end: 'bottom center',
          },
        })
      })
    }
  }, [textRef])

Screenshot 2023-04-02 at 14 04 05

Framer motion Next js Pages Router Using Split-type and LayoutID for loader

Link to working example of the issue i'm facing example

So i have a loader that runs an animation and then on complete sets a state so i show the page content.

In the loader.js i have an element layoutID="name" and in the page i have a corresponding element layoutID="name" which is inside a splitText component

When it loads its meant to animate into the pages element position, similar to what this example does with the large image https://pageloader-3cf2b.web.app/

I've also tried putting the element outside the splitText component layoutID="name2", but still some issues.

Any help would be great

SEO compatibility

Does using this library interfere with Google's ability to index the content?

Words should not break

I believe there's some white-space: nowrap missing from the word elements as they seem to break in all the examples I'm seeing or doing. Could this be added?

nasted element inside the target disappeared

I'm new to SplitType, I just wanted to do a simple animation for the header of my website, it's working very nicely but I have a problem with the nested element.

HTML :

      <h1 class="main-heading all-heading-setting" id="main-heading">
        Lorem, ipsum dolor. <span class="gradiant-text">lorem</span> Lorem ipsum dolor sit amet consectetur adipisicing!
      </h1>

the css of the target and gradiant-text element :


.main-heading {
  font-size: 5rem;
  line-height: 1;
  max-width: 75%;
  text-shadow: 0 8px 16px rgb(0 0 0 / 0.1);

  /*for splitType package*/
  font-kerning: none;
}


.gradiant-text {
  text-transform: capitalize;
  -webkit-text-fill-color: transparent;
  background-image: linear-gradient(
    90deg,
    #28abe1 15%,
    #ff729f 50%,
    #f18f01 85%
  );
  -webkit-background-clip: text;
  background-clip: text;
  display: inline;

   /*for splitType package*/
   font-kerning: none;
}

javascript :


import SplitType from "split-type";
import { animate, stagger } from "motion";

// const headingMain = document.querySelector(".main-heading");
// const headingSub = document.querySelector(".sub-heading");

const headingsub = new SplitType("#sub-heading", {types: "lines"});
// const headingMain = new SplitType("#main-heading", {types: "words"});
const headingMain = SplitType.create('#main-heading');
const bringThemAllTogether = [...headingsub.lines, ...headingMain.words];

export const startAnimation = () => {
    animate(bringThemAllTogether, {y: [24, 0], opacity: [0, 1]}, {duration:[1], delay: stagger(0.08)});
}

image

maybe there is some css rules in the .gradiant-text class that conflict with SplitType? help please

Allow users to override the display and position style on nested elements

Hey there, great plugin!

I did run into a little issue though which might be fixable?

When another element is being found you make sure to preserve that element; which is great. However the fact that splitType is giving these elements inline styling for display and position is a bit less great ;) These elements also don't get any classname so we can't override them with !important (not that we want that, but even this is not an option).

Here's a quick codepen illustrating the issue:
https://codepen.io/robinpoort/pen/mdvLaKW

As you can see, the span element inside the h2 get display: inline-block and position: relative applied to it. Even if the span has a class that has other values (the second example), these values will simply be overwritten. In my case (the real project i'm working on) the span can't even have a class since the headings are coming from a system I have little control over :(

I can think of a few possible solutions:

  1. Instead of using inline styles; add a class that has position: relative; display: inline-block; so this class is easily overwriteable. This solution would not be optimal since you can't target individual instances on the page this way.
  2. Next to the types option add a 'inline-styleoption where you can assign a list likeinline-block, relative(the default) but alsoinline, staticorblock, sticky` for example. This would be a nice addition since you can style different instances on the page accordingly.
  3. A third option might be to be to add the ability to add a custom class to these span elements. This way we can use !important to override the default behavior. Either that; or remove the inline styling when a custom class is set so you can set your own.

Would any of the above even be possible?

Not sure if this is clear or not. Let me know if you need more explanation or examples :-)

Lines split incorrectly on Astro with View Transitions API

I have this website https://www.minov.studio/en/, which uses split type to split words and lines, and then animates each one of them using an animation library. It works perfectly when loading the page for the first time, the problem is after navigating to any other page and then going back, the lines are split incorrectly. Although sometimes it can take more than one try to achieve this.

First load:
image
Second load:
image

However, when using a browser not based on chromium like Firefox, the fallback behaviour is normal page load and the lines are always split correctly. So I'm sure the problem causing this must be something related to the client-side navigation behaviour of Astro.

Code:

<script> 
import SplitType from "split-type"

const animationsInit = () => {
    const heading = new SplitType(".fade-h", { types: "words" })
    const paragraph = new SplitType(".fade-p", { types: "lines" })

    // Setting the opacity of the elements to 0, to be able to animate them using an animation library
    line.forEach(function (element) {
      element.style.opacity = 0
    })
    const sectionElements = [...heading.words, ...paragraph.lines]
    sectionElements.forEach(function (element) {
      element.style.opacity = 0
    })

    // Code which animates the elements (skipped)
}

// Executing the function on page load
animationsInit();

// Executes animationInit() when navigation between pages
document.addEventListener("astro:after-swap", animationsInit)
</script>

Here's the link for anyone interested in knowing more about View Transitions: https://docs.astro.build/en/guides/view-transitions/#overview

TypeScript type declaration file

If you want I can write a TypeScript type declaration file for this package so that TS developers can utilise the type-checking feature of the language as they use this package. Let me know if you are interested.

Not working with react next js

Hello,

I was using an old version of splittype and recently migrated to next js.
I tried to use your new version import SplitType from 'split-type' but I get the following error:

Server Error
SyntaxError: Unexpected token 'export'

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source
external%20%22split-type%22 (1:0) @ eval

> 1 | module.exports = require("split-type");

Any idea how to solve this?

'isSplit' is missing the type declarations

As the title says, isSplit is missing in the type declarations so this will throw an error:

const text = new SplitType(textRef.current, {
  types: 'lines',
  tagName: 'span',
});

text.isSplit // Property 'isSplit' does not exist on type 'SplitType'. Did you mean 'split'? ts(2551)

Google Tranlation

First of all, thanks for the great script. It works great on my site. I only have one major issue. When a person uses the google translator, all the text that is broken down into words and chars will not translate. Actually even worse:

Original:
image

After using google translator:
image

Any idea how to fix this?

Cheers, Daniel

How do we return type back to original html content after animation is finished??

How do we Implement the Reverting Split Text after animated is finished?

If use your gsap example of

`const text = new SplitType('#target', { types: 'words, chars' })

// Animate characters into view with a stagger effect
gsap.from(text.chars, {
opacity: 0,
y: 20,
duration: 0.5,
stagger: { amount: 0.1 },
})`

How do we use SplitType.revert('#target') to return text to original html

SplitType not working as expected in WebFlow project

I have no idea what's causing this bug. When i go to my page, sometimes it will split the lines correctly and sometimes it will split additional line. I get the bug 1 out of 10 if I do refresh, mostly when i first open the tab with the link.

Please help how can I prevent this. thanks

Correct:
Screenshot 2023-01-17 at 19 26 46

With bug:
Screenshot 2023-01-17 at 19 26 21

Here is the link: https://creatd-bb.webflow.io/

wrap elements in custom element to animate

Got the following code in react

`
 import React, { useEffect, useRef } from "react";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import SplitType from "split-type";

interface SplitProps {
  children: React.ReactNode;
  splitMode: String;
  delay: number;
}

const Split = ({ children, splitMode, delay = 0 }: SplitProps) => {
  const trigger = useRef<HTMLDivElement>(null);
  const target = useRef<HTMLDivElement>(null);

  useEffect(() => {
    gsap.registerPlugin(ScrollTrigger);

    const init = () => {
      split();
    };

    const animate = (text) => {
      gsap.from(text, {
        delay: delay,
        y: "105%",
        duration: 0.5,
        stagger: 0.05,
        ease: "power2.in",
        force3D: true,
        scrollTrigger: {
          trigger: trigger.current,
          scrub: false,
        },
      });
    };

    const splitChars = () => {
      const text = new SplitType(target.current!, { splitClass: "split-text", types: "chars" });
      animate(text.chars);
    };

    const splitLines = () => {
      const text = new SplitType(target.current!, { splitClass: "split-text", types: "lines" });
      animate(text.lines);
    };

    const splitWords = () => {
      const text = new SplitType(target.current!, { splitClass: "split-text", types: "words" });
      animate(text.words);
    };

    const split = () => {
      if (splitMode === "chars") {
        splitChars();
      } else if (splitMode === "lines") {
        splitLines();
      } else if (splitMode === "words") {
        splitWords();
      }
    };

    init();
  }, []); // Empty dependency array ensures that the effect runs once after the initial render

  return (
    <span ref={trigger} className="inline-block">
      <span ref={target} className="inline-block overflow-hidden overflow-clip">
        {children}
      </span>
    </span>
  );
};

export default Split;
`

This outputs code like this for example if we are using lines

<span class="inline-block overflow-hidden overflow-clip">
       <div class="split-text line">Lorem ipsum dolor sit amet, consectetur..</div>
        <div class="split-text line">Lorem ipsum dolor sit amet, consectetur..</div>
</span>

What i want to do is wrap the

div in another div that will act as the overflow-hidden, so the output would look like

<span class="inline-block overflow-hidden overflow-clip">
       <div class="split-text-wrapper">
                <div class="split-text line">Lorem ipsum dolor sit amet, consectetur..</div>
        </div>
        <div class="split-text-wrapper">
                <div class="split-text line">Lorem ipsum dolor sit amet, consectetur..</div>
        </div>
</span>

is this possible?

Add index variables for animating using CSS

I just discovered the lib recently, it works great and is very lightweight, thanks for all the work 🙌

In order to animate characters, words and lines using CSS, it would be amazing to have some variables attached to each span, like so:

<!-- for chars -->
<span class="word" style="--index-word: 0; display: inline-block;">
    <span class="char" style="--index-char: 0; display: inline-block;">W</span>
    <span class="char" style="--index-char: 1; display: inline-block;">o</span>
    <span class="char" style="--index-char: 2; display: inline-block;">r</span>
    <span class="char" style="--index-char: 3; display: inline-block;">d</span>
</span>

<!-- for words -->
<span class="word" style="--index-word: 0; display: inline-block;">Word1</span>
<span class="word" style="--index-word: 1; display: inline-block;">Word2</span>

<!-- for lines: "--index-line: x;" -->

That way, it would really help animate text using pure CSS transitions and add a stagger effect with a simple transition-delay: calc(50ms * var(--index-word)), then trigger visibility classes with an IntersectionObserver for instance.

I've implemented it in a similar way with a rusty function that only splits words and chars independently: (using Svelte each loop, adding the index to it)

<span class="word">
    {#each split as char, i}
        <span class="char" style:--i-c={i}>{char}</span>
    {/each}
</span>

Error when splitting text containing line breaks

Description

SplitType fails with an error when the target element contains <br> tags. This only occurs when splitting text into both lines and words.

Steps to reproduce

HTML

<div id="target">foo <br> bar </div>

Javascript

const text = new SplitType('#target', { types: 'lines, words' })

Live example

Expected result

It should respect <br> tags when splitting text into lines. The above code should produce the following html

<div id="target">
  <div class="line">
    <div class="word">foo</div>
  </div>
  <div class="line">
    <div class="word">bar</div>
  </div>
</div>

Actual result

Uncaught TypeError: Cannot read property 'concat' of null
    at split-type.js:567
    at Array.reduce (<anonymous>)
    at splitSingleElement (split-type.js:512)
    at split-type.js:875
    at Array.forEach (<anonymous>)
    at SplitType.split (split-type.js:872)
    at new SplitType (split-type.js:839)
    at pen.js:7

only set nested html elements to relative if needed

I have a global script that automatically adds a dynamic button to headline texts based on whether a nested span element within the headline has a specific target class. This dynamically inserted button is absolutely positioned relative to the span element.

Example markup:

  <h2>Text that is split and I want to add a legal disclaimer button <span class="js-legal-text">to</span>.</h2>

Example markup after my script runs:

  <h2>Text that is split and I want to add a legal disclaimer button <span class="js-legal-text">to <button>*</button></span>.</h2>

My script works beautifully except for animated headlines that use the splittype library. An extra space is added in between my button and the span wrapped text. After digging into it I noticed that it was this SplitType library that changes my button from an absolute to a relative positioned button. I tried using the absolute: true setting but this just breaks the layout even more since SplitType then injects more style attributes to the button which causes even more conflicts with my style rules from my original script.

I was wondering would it be possible to modify SplitType so that it does a check for any inline styles before forcing the div to be relatively positioned?

something like (untested pseudocode):

split.js

  ...
  
  if (!data.get(node).isRoot) {
      node.style.display = 'inline-block'
      
      if (isEmpty(node.style.position)) {
        node.style.position = 'relative'
      }
      
     ...

Is it possible to delete the created SplitType instance?

Is it possible to correctly remove an existing SplitType instance when, for example, unmounting a vue component? Otherwise, if I unmount using revert on the next connections for the first time, I get no text split at all, and then I get a double split. Each letter is perceived as a separate word and turns into two additional elements .word and .char

Add type support for types property in options

Right now types in the options? parameter does not have any strict typing.

You can leverage template literals to give first-class typing for it:

type ElementSplitType = 'lines' | 'words' | 'chars'
type TypesAgg =
  | ElementSplitType
  | `${ElementSplitType} ${ElementSplitType}`
  | `${ElementSplitType} ${ElementSplitType} ${ElementSplitType}`

This will cover all bases and give excellent autocomplete suggestions.

Break lines with strong div

Hello @lukePeavey ,

Thank you already for this little library ! Well seen the takeover of splitText from Gsap. Less heavy in addition to size :)

However, I have a question that I still can't manage regarding the split lines and the or or tags.

Here is my HTML code :

<p>Installée dans un cabinet à Saint-Raphaël, auprès de mes amis Chiropracteur je vous
                        propose un accompagnement personnalisé à travers une approche holistique qui se traduit par la
                        considération de ses 3 points : <strong>Le bien-être psycho-émotionnel, physiologique (corps), et par le mode de vie.</strong></p>

My JS code :

window.$splitLines.each(function () {
                let $el = $(this),
                    $animText = $el.find($splitTextElements);

                $animText.each(function () {
                    let $lines = $(this);
                    SplitType.create($lines, {
                        types: "lines, words",
                        lineClass: "overflow-split-line",
                        wordClass: 'inline-block',
                    });
                    gsap.set(".overflow-split-line", {
                        overflow: "hidden"
                    });
                    gsap.set('.overflow-split-line > div, .overflow-split-line strong > div', {
                        yPercent: 105
                    });
                });
            });

Anyway I always have a newline with the tag, I also don't understand the part you mention in nested-elements

See my screenshot : https://ibb.co/tz4v0KX

Am I doing something wrong ?

Thanks for your return :) Regards Nicolas

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.