<nav id="nav">
  <button id="chars">chars</button>
  <button id="words">words</button>
  <button id="lines">lines</button>
  <button id="charsWordsLines">chars words and lines</button>
  <button id="revert">revert</button>
</nav>  
  
<div id="demo">
  <div id="quote">SplitText supports <strong>nested tags</strong> like  <span class="code">&lt;span&gt;</span>, <span class="code">&lt;strong&gt;</span>, and <span class="code">&lt;em&gt;</span>. Want to preserve a link? <a href="https://www.greensock.com" target="_blank">No problem</a>. You can even <em>GO NUTS with EMOJI</em> 🟣 🔶 🩵</div>
  </div>
</div>
  
* {
  box-sizing: border-box;
}

html,
body {
  height: 100vh;
  overflow: hidden;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 2rem;
  padding: 2rem;
}

strong {
  color: var(--color-orangey);
}

.highlight {
  color: red;
  font-family: serif;
}

.code {
  font-family: Courier;
  color: var(--color-surface-white);
}

#demo {
  position: relative;
}
#quote {
  font-size: clamp(2rem, 6rem, 4.5vw);
  line-height: 1.2;
  color: #dfdcff;
  text-align: center;
}

button {
  font-size: 0.75rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
}

#nav {
  padding-bottom: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75em;
  flex-wrap: wrap;
}

a:visited,
a:link,
a:active {
  color: var(--color-orangey);
  text-decoration: none;
  display: inline-block;
}

a:hover {
  background-color: var(--color-orangey);
  color: var(--color-surface-white);
}

span {
  display: inline-block;
}
/*

More SplitText demos on Codepen: https://codepen.io/collection/KiEhr

See https://www.greensock.com/splittext/ for details. 

This demo uses SplitText which is a membership benefit of Club GreenSock, https://www.greensock.com/club/
*/

var $quote = $("#quote"),
    mySplitText = new SplitText($quote, {type:"words"}),
    splitTextTimeline = gsap.timeline();

gsap.set($quote, {perspective:400});

//kill any animations and set text back to its pre-split state
function kill(){
  splitTextTimeline.clear().time(0);
  mySplitText.revert();
}

$("#chars").click(function() {
  kill();
  mySplitText.split({type:"chars, words"}) 
  splitTextTimeline.from(mySplitText.chars, {duration: 1, scale:4, autoAlpha:0,  rotationX:-180,  transformOrigin:"100% 50%", ease:"back", stagger: 0.02});
})

$("#words").click(function() {
  kill();
  mySplitText.split({type:"words"}) 
  $(mySplitText.words).each(function(index,el) {
    splitTextTimeline.from(el, {duration: 1, opacity:0, force3D:true}, index * 0.01);
    splitTextTimeline.from(el, {duration: 1, scale:index % 2 == 0  ? 0 : 2}, index * 0.01); 
  });
})

$("#lines").click(function() {
   kill();
   mySplitText.split({type:"lines"}) 
   splitTextTimeline.from(mySplitText.lines, {duration: 2, opacity:0, x: -100, stagger: 0.1, ease: "expo.out"});
 
})

$("#charsWordsLines").click(function() {
  kill();
  mySplitText.split({type:"chars, words, lines"}) 
  splitTextTimeline.from(mySplitText.chars, {duration: 0.6, autoAlpha:0, scale:3, force3D:true, stagger: 0.02}, 0.5)
    .to(mySplitText.words, {duration: 0.2, color:"#ff8709", scale:0.9, stagger: 0.1}, "words")
    .to(mySplitText.words, {duration: 0.4, color:"white", scale:1, stagger: 0.1}, "words+=0.1")
    .to(mySplitText.lines, {duration: 0.5, x:100, autoAlpha:0, stagger: 0.2}) 
})

//revert the text back to its pre-split state
$("#revert").click(function() {
  mySplitText.revert(); 
})

External CSS

  1. https://codepen.io/GreenSock/pen/xxmzBrw/fcaef74061bb7a76e5263dfc076c363e.css

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js
  3. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/SplitText3.min.js