JSFiddle - React, Tailwind, and code Playground

by mihaibirsan

HTML

<div class="description">
  <p class="typewriter">
    Hello <strong>Merwllyra</strong>!<br>
    You were waiting for the taxi boat in the port and fell asleep.
  </p>
</div>

CSS

html, body { background: #1F2227; }
.description {
  width: 15em;
  background: #FFFAE4;
  color: #827256;
  padding: 1em;
  border-radius: .5em;
}
.description p {
  margin: 0;
}

/* NOTE: Many of these values are computed manually and would better be extracted into SCSS. However, I wasn't able to get SCSS to work, so this version of the fiddle just has the numbers. */

.typewriter {
  line-height: 1.2em;
}

.typewriter > div {
  height: 1.2em;
  overflow: hidden;
  animation: reveal 1s steps(17, jump-none) both; /* NOTE: Prefer `linear` instead of `steps` with variable-width fonts. */
}
.typewriter > div > div {
  width: 15em; /* NOTE: This width must be fixed here. So the reveal can work. */
}

.typewriter > div:nth-child(2) {
  width: 0;
  animation-delay: 1s;
}
.typewriter > div:nth-child(3) {
  animation-delay: 2s;
}

.typewriter > div:nth-child(2) > div {
  margin-top: -1.2em;
}
.typewriter > div:nth-child(3) > div {
  margin-top: -2.4em;
}


@keyframes reveal {
  from { width: 0; }
  to { width: 100%; }
}

JavaScript

// NOTE: This duplication is unnecessarily complex in plain JS; consider implementing using your favorite library
const el = document.querySelector('p.typewriter');
const elInnerHTML = el.innerHTML;
el.innerHTML = '';
for (let i = 0; i < 3; i++) {
	const divEl = document.createElement('div');
  divEl.classList.add('typewriter-'+(i+1))
  const innerDivEl = document.createElement('div');
  innerDivEl.innerHTML = elInnerHTML;
  divEl.appendChild(innerDivEl);
  el.appendChild(divEl);
}