skip to Main Content

How can I create dynamic letter spacing for a line of text that starts with 100% width of a container and reduces as the screen size gets smaller? I want the letter spacing to adjust based on the container’s width, and the text’s width should be recalculated whenever the window is resized.

I am getting letter spacing but not the width of the container.

$(document).ready(function () {

    function adjustLetterSpacing() {
        var containerWidth = $(".container").width();
        var textElement = $(".dynamic-text");
        var maxWidth = containerWidth - 50;
        var textWidth = textElement.width();
        var letterSpacingValue = 0;

        if (maxWidth > textWidth) {
            var textLength = textElement.text().length;
            letterSpacingValue = (maxWidth - textWidth) / (textLength - 1);
        }

        $(".dynamic-text").css("letter-spacing", Math.max(0, letterSpacingValue) + "px");
    }

    // Initial adjustment on page load
    adjustLetterSpacing();

    $(window).on("resize", adjustLetterSpacing);

});
.container {
  width: 1200px;
  }

.dynamic-text {
    white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<div class="container">
  <p>
      <span class="dynamic-text">
          Lorem ipsum dolor sit amet
      </span>
  </p>
</div>

Any guidance on how to implement this effect would be appreciated.

2

Answers


  1. You could do something like this with Vanilla JS.

    We add a "hidden/interim" element to the document with the text, grab it’s width.

     const hiddenEl = document.createElement('span');
      hiddenEl.textContent = text;
      hiddenEl.style.visibility = 'hidden';
      document.body.appendChild(hiddenEl);
    

    We could grab that the first time and cache it if we wanted.

    Then we just figure out what the letter spacing needs to be based on the overall width minus the texts original width.

    div.style.letterSpacing = `${(width - absoluteWidth) / text.length}px`;
    
    function setLetterSpace(el) {
      const width = el.getBoundingClientRect().width;
      const text = el.textContent.trim();
    
      const hiddenEl = document.createElement('span');
      hiddenEl.textContent = text;
      hiddenEl.style.visibility = 'hidden';
      document.body.appendChild(hiddenEl);
      const absoluteWidth = hiddenEl.getBoundingClientRect().width;
      document.body.removeChild(hiddenEl)
    
      div.style.letterSpacing = `${(width - absoluteWidth) / text.length}px`;
    }
    
    
    const div = document.querySelector('div');
    setLetterSpace(div);
    
    window.addEventListener('resize', () => {
      setLetterSpace(div);
    });
    <div>Some text in here</div>
    Login or Signup to reply.
  2. We can just make the span as wide as the div. and give the letter spacing as width/totalLetters.

    But at very first we will also store the actual width of the letters because there are words too with spaces.

    <!DOCTYPE html>
    <html>
    <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
    $(document).ready(function () {
    var sizeOfAllLetters = $(".dynamic-text").width();
        function adjustLetterSpacing() {
            var containerWidth = $(".container").width();
            var textElement = $(".dynamic-text");
            var totalLetters = textElement.text().length;
            textElement.width(containerWidth);
            textElement.css("letter-spacing",containerWidth/totalLetters);
            //console.log(containerWidth/totalLetters)
            }
    
        // Initial adjustment on page load
        adjustLetterSpacing();
        
        $(window).on("resize", adjustLetterSpacing);
    });
    </script>
    
    <style>
    .container {
      width: 1200px;
      /*margin-inline:auto;*/
      }
    
    .dynamic-text {
        white-space: nowrap;
        /*margin-inline:auto;*/
        background:grey;
    
    }
    </style>
    
    </head>
    <body>
    <div class="container">
      <span class="dynamic-text">Lorem ipsum dolor sit amet</span>
    </div>
    </body>
    </html>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search