JSFiddle - React, Tailwind, and code Playground

by gRoberts

HTML

<div class="lines-shift-container" style="--shift-delay: var(--shift-base-delay);">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem quasi magnam quis, officiis consectetur velit omnis porro? Harum cum, culpa ipsum reiciendis aperiam dignissimos quis sunt consequuntur, odio, nemo illo.</div>

CSS

--shift-base-delay: 200ms;
--shift-delay: 200ms;

.lines-shift-container {
  --shift-base-delay: 140ms; /* 200ms default */
  --anim-duration: calc(var(--shift-base-delay) * 10);
  --shift-delay: 0ms;
  visibility: hidden;
}

.lines-shift-container--200ms-delay { --shift-delay: var(--shift-base-delay); }
.lines-shift-container--400ms-delay { --shift-delay: calc(var(--shift-base-delay) * 2); }
.lines-shift-container--600ms-delay { --shift-delay: calc(var(--shift-base-delay) * 3); }

.shift-line {
  --line-number: var(--nth-child-idx);
  overflow: hidden;
  display: inline-flex;
  position: relative;
  width: 100%;
  /*line-height: 1em;*/
  /*background-color: rgba(255, 0, 0, 0.2);*/
}

/*.shift-line sup {
font-size: 0.5em;
top: -.7em;
}*/

.shift-line > span {
  display: inline-block;
  will-change: opacity, transform;
  /*transition: transform 200ms cubic-bezier(.46,.45,.39,1.14);*/
  transition: opacity calc(var(--anim-duration) / 3) linear, transform var(--anim-duration) cubic-bezier(0.19, 1, 0.22, 1);
  /*transform: translateY(0%);*/
  transform: translateY(103%);
  /*opacity: 0;*/
  transition-delay: calc(var(--shift-base-delay) + var(--shift-delay) + (var(--anim-duration) / 10) * (var(--line-number) - 1));
}

body.page--loaded:not(.pace-running) .lines-shift-container,
body.wp-admin .lines-shift-container {
  visibility: initial;
}

body.page--loaded:not(.pace-running) .lines-shift-container:not(.lines-shift-container--vt) .shift-line > span {
  transform: translateY(0%);
  /*opacity: 1;*/
}

body.page--loaded:not(.pace-running) .visible-tag--visible .lines-shift-container.lines-shift-container--vt .shift-line > span {
  transform: translateY(0%);
}

body.wp-admin .shift-line > span {
  transform: translateY(0%);
}

JavaScript

function nextAnimationFrame() {
    return new Promise(function(resolve, reject) {
        window.requestAnimationFrame(function() {
            window.requestAnimationFrame(resolve);
        });
    });
}

function transitionEnd(target) {
    return new Promise(function(resolve, reject) {
       target.addEventListener('transitionend', resolve, {once: true});
    });
}

(function() {
	console.log(document);
    if('fonts' in document) {
        document.fonts.ready.then(async function() {
            processShiftLineContainers();
            await nextAnimationFrame();
            document.body.classList.add('page--loaded');
        });
    } else {
        window.addEventListener('DOMContentLoaded', async function() {
            processShiftLineContainers();
            await nextAnimationFrame();
            document.body.classList.add('page--loaded'); 
        });
    }

    let resizeTimeout = null;
    window.addEventListener('resize', function() {
        clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(processShiftLineContainers, 1000);
    });
})();

function processShiftLineContainers() {
    const shiftContaners = Array.from(document.querySelectorAll('.lines-shift-container'));
    shiftContaners.forEach(c => wrapLines(c, '<span class="shift-line"><span>', '</span></span>'));
}

function wrapLines(target, before, after) {
    let lines = detectLines(target);
    lines = lines.map(l => before + l + after);
    let html = lines.join(' ');
    target.innerHTML = html;
}

function detectLines(target) {
    const text = target.textContent;
    const words = text.split(' ');
    const div = document.createElement('div');

    // Creating copy of text container with text affecting properties
    const tstyle = window.getComputedStyle(target);
    const rect = target.getBoundingClientRect();
    div.style.width = rect.width + 'px'; //tstyle.getPropertyValue('width');
    div.style.fontFamily = tstyle.getPropertyValue('font-family');
   ...