Search code examples
jqueryhtmlfontskerningletter-spacing

Jquery - Kerning Paragraph Text to Fit to Parent


I am attempting to fit dynamically generated text into a parent div. The issue is that the length of text varies from day to day, and at times overflows the parent div. I have seen plenty of forums that scale text size, or stretches the content to fill the container, however, the content I use must maintain a set font size and line height.

I am looking for a Jquery based kerning method where I can set the maximum negative and positive kerning limits. If the limit is reached, with the content still not fitting, then the last sentence will be removed and the kerning procedure will begin again. This will repeat as necessary until the content fits the parent.

https://jsfiddle.net/j61xke31/

HTML:

<div  class="parent">
    <p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vitae ex eget eros posuere ullamcorper non id magna. Suspendisse augue lorem, ornare ut aliquam eu, molestie nec mauris. In luctus erat sit amet accumsan laoreet. Fusce a dolor in ex efficitur
cursus ac id orci. Integer quis quam molestie elit posuere maximus eget a diam. Proin lacinia pharetra lacus rutrum vestibulum. Etiam id augue mi. Nam efficitur pellentesque varius. Curabitur dui nisi, consectetur eu porttitor nec, sodales sed diam.
Phasellus gravida molestie fermentum. Curabitur non felis sit amet nisi facilisis tincidunt. Suspendisse quis tempus sem.
    </p>
</div>

CSS

.parent {
  width: 250px;
  height: 182px;
  border: 1px solid black;
}

.content {
  font-size: 12px;
  line-height: 14px;
  font-family: Arial, Sans Serif;
  letter-spacing: 0;
  margin: 0
}

Any help on the matter is appreciated.


Solution

  • With jQuery this is quite simple:

    Create a recursive function ex: kerningText.

    Inside that function get the current parent height, current content height and current content letter-spacing for checking if a reduce letter-spacing is needed or not (or stop if the letter-spacing lower bound reached).

    var parentHeight = $('.parent').innerHeight();
    var contentHeight = $('.content').innerHeight();
    var contentLS = parseFloat($('.content').css('letter-spacing'));
    

    (note: use parseFloat so you get -0.1 from -0.1px, otherwise you can't do - 0.1 in the 2nd line of code)

    If your content is higher than the parent means you have an overflow and your lowest letter-spacing limit is not reached, you need to reduce the letter-spacing by 0.1px:

    $('.content').css('letter-spacing', contentLS - 0.1);
    

    Then call yourself and repeat the process until you fit the parent or letter-spacing limit reached.

    $(document).ready(function() {
      function kerningText() {
        var parentHeight = $('.parent').innerHeight();
        var contentHeight = $('.content').innerHeight();
        var contentLS = parseFloat($('.content').css('letter-spacing'));
    
        // check if letter-spacing bigger than the lower bound -1
        if (contentHeight > parentHeight && contentLS > -1) {
          //reduce the letter-spacing by 0.1
          $('.content').css('letter-spacing', contentLS - 0.1);
          //recursive until the content fit
          kerningText();
        }
      }
    
      $('#kerningBtn').on('click', kerningText);
    });
    .parent {
      width: 250px;
      height: 182px;
      border: 1px solid black;
    }
    
    .content {
      font-size: 12px;
      line-height: 14px;
      font-family: Arial, Sans Serif;
      letter-spacing: 0;
      margin: 0
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <button id="kerningBtn">Kerning Text Now</button>
    
    <div class="parent">
      <p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vitae ex eget eros posuere ullamcorper non id magna. Suspendisse augue lorem, ornare ut aliquam eu, molestie nec mauris. In luctus erat sit amet accumsan laoreet. Fusce a dolor in ex efficitur
        cursus ac id orci. Integer quis quam molestie elit posuere maximus eget a diam. Proin lacinia pharetra lacus rutrum vestibulum. Etiam id augue mi. Nam efficitur pellentesque varius. Curabitur dui nisi, consectetur eu porttitor nec, sodales sed diam.
        Phasellus gravida molestie fermentum. Curabitur non felis sit amet nisi facilisis tincidunt. Suspendisse quis tempus sem.
      </p>
    </div>