Wrap each letter in <span> element (using RegExp)

Using RegExp /\S/g and replace method of the String we can wrap each letter in HTML Element (e.g. <span>). Then we can add class to those elements and manipulate them / change them through CSS / JS

by Konstantin Rouda

HTML

<section class="c-canvas">
  <h1 class="o-title c-canvas__title" id="text">Hello world!</h1>
</section>

CSS

HTML {
  /*using system font-stack*/
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  font-size: 115%; /*~18px*/
  font-size: calc(16px + (30 - 16) * (100vw - 300px) / (1300 - 300) );
  line-height: 1.5;
  box-sizing: border-box;
}

BODY {
  margin: 0;
  color: #3a3d40;
  background: rgb(253, 254, 253);
}

*, *::before, *::after {
  box-sizing: inherit;
  color: inherit;
}


/*Actual Style*/
.c-canvas {
  padding-top: 1rem;
  text-align: center;
  border: 1px solid cornflowerblue;
}

.o-title {
}

.c-canvas__title {
  border: 1px solid;
}


.o-letter {
  outline: 2px solid firebrick;
  outline-offset: -2px;
}

JavaScript

;(function () {
	"use strict";
  
  const title = document.getElementById("text");
  
  
  function sliceTextToSpanElements (text, spanClass) {
    /*
      /\S/ - all not white space elements
      $& - Entire matched string
      more info in: https://twitter.com/KonstantinRouda/status/899286318773088256
    */
  	return text.replace(/\S/g, "<span class=" + spanClass + ">$&</span>");
  };
  
  
  title.innerHTML = sliceTextToSpanElements(title.innerText, "o-letter");
  
  
})();


/*
Idea from:
https://codepen.io/cobra_winfrey/pen/opZgWL
*/