CSS text justify with letter spacing

Groo picture Groo · Dec 4, 2010 · Viewed 26.9k times · Source

Is there a way to automatically justify words using letter spacing, each in its row, to a defined width, using CSS?

For example, "Something like this" would look, well, something like this:

"Something like this" would look something like this

Is there a non-obtrusive way to apply such styling to my text? I believe pure CSS doesn't have this option (at least not with CSS versions before 3, CSS3 seems to have a text-justify property, but it's not well supported yet), so js solutions would be fine also.

Answer

Dark Falcon picture Dark Falcon · Dec 4, 2010

Here's a script which can do it. It isn't pretty, but maybe you can hack it to meet your needs. (Updated to handle resizing)

function SplitText(node) {
  var text = node.nodeValue.replace(/^\s*|\s(?=\s)|\s*$/g, "");

  for (var i = 0; i < text.length; i++) {
    var letter = document.createElement("span");
    letter.style.display = "inline-block";
    letter.style.position = "absolute";
    letter.appendChild(document.createTextNode(text.charAt(i)));
    node.parentNode.insertBefore(letter, node);

    var positionRatio = i / (text.length - 1);
    var textWidth = letter.clientWidth;

    var indent = 100 * positionRatio;
    var offset = -textWidth * positionRatio;
    letter.style.left = indent + "%";
    letter.style.marginLeft = offset + "px";

    //console.log("Letter ", text[i], ", Index ", i, ", Width ", textWidth, ", Indent ", indent, ", Offset ", offset);
  }

  node.parentNode.removeChild(node);
}

function Justify() {
  var TEXT_NODE = 3;
  var elem = document.getElementById("character_justify");
  elem = elem.firstChild;

  while (elem) {
    var nextElem = elem.nextSibling;

    if (elem.nodeType == TEXT_NODE)
      SplitText(elem);

    elem = nextElem;
  }
}
#character_justify {
  position: relative;
  width: 40%;
  border: 1px solid red;
  font-size: 32pt;
  margin: 0;
  padding: 0;
}

#character_justify * {
  margin: 0;
  padding: 0;
  border: none;
}
<body onload="Justify()">
  <p id="character_justify">
    Something<br/> Like
    <br/> This
  </p>
</body>