Split Text - Hover Letters

Create interactive letter effects that respect user's motion preferences.

Full article · Video on YouTube · Source on Github

HTML

<h1 split-by="letter" letter-animation="hover">
  hover-me letters
</h1>

CSS


        @media (prefers-reduced-motion:no-preference) {
  [letter-animation=hover]:hover>span {
    transform: scale(.75) perspective(1px)
  }

  [letter-animation=hover]>span {
    transition: transform .3s ease;
    cursor: pointer;
    will-change: transform
  }

  [letter-animation=hover]>span:hover {
    transform: scale(1.25) perspective(1px)
  }
}
        

JS


        const span = (text, index) => {
  const node = document.createElement('span')

  node.textContent = text
  node.style.setProperty('--index', index)
  
  return node
}

const byLetter = text =>
  [...text].map(span)

const {matches:motionOK} = window.matchMedia(
  '(prefers-reduced-motion: no-preference)'
)

if (motionOK) {
  const splitTargets = document.querySelectorAll('[split-by]')

  splitTargets.forEach(node => {
    let nodes = byLetter(node.innerText)

    if (nodes)
      node.firstChild.replaceWith(...nodes)
  })
}