Search code examples
cssjustifyletter-spacingtext-justify

CSS text justify with letter spacing


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.


Solution

  • 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>