Resizing font based on html length

256 views Asked by At

I know there are a lot of similar posts, but I have not thus far been able to solve this.

context:
User selects a home,
homes have unique titles,
depending on title, resize font to prevent overflow

JS Fiddle: https://jsfiddle.net/9uvpun5o/3/

$(function() {
    var that = $('#title'),
        planName = that.html().length
    ;
    // depending on html length, update font-size
    if(planName > 30) {
        that.css('font-size', '10px');
    } else if(planName > 20) {
        that.css('font-size', '12px');
    } else if(planName > 10) {
        that.css('font-size', '15px');
    }
});

Font is sized according to html length, but I need this to be reactive. I tried creating an .on("change") event, but failed to implement correctly. Help?

Right now I'm just updating the title from console,
$('#title').html("big long description thing");

But, this will be done by selecting from a modal menu in the future.

3

There are 3 answers

4
MaurĂ­cio Araldi On BEST ANSWER

EDIT

Ok, now I got it. Your JS should be this then:

$(function() {
    $('#title').on('DOMSubtreeModified', function() {
        var title = $('#title'),
            planName = title.html().length;

        // depending on html length, update font-size
        if(planName > 30) {
            title.css('font-size', '10px');
        } else if(planName > 20) {
            title.css('font-size', '12px');
        } else if(planName > 10) {
            title.css('font-size', '15px');
        }
    });

     $('li').on('click', function() {
         $('#title').text( $(this).text() );
     });
});

The DOMSubtreeModified should fire whenever the content of the element changes (as this modifies the DOM Subtree). The 'click' part is not necessary, but I've kept it for testing purposes.

According to Dottoro, Opera doesn't support this event and IE 9 and below may not support or be buggy.

For more options and informations, check these other StackOverflow question:


By what you said, an user will "select a unit":

use case: User selects a unit, units have unique titles, depending on title, resize font to prevent overflow

So, you need to change the font-size as part of this action. I used your code to make an example:

HTML

<ul>
    <li>On load, font size is set depending on length of title.</li>
    <li>However, I want this to be reactive...</li>
    <li>Change the length of Title and hit run</li>
    <li>Try clicking these itens</li>
    <li>You will see</li>
<ul>
<br/><br/>
<span id="title">TEST TEST</span><br/>

JS

$(function() {
    $('li').on('click', function() {
       var titleEl = $('#title').text( $(this).text() ),
           planName = titleEl.text().length;

        // depending on text length, update font-size
        if (planName > 30) {
            titleEl.css('font-size', '10px');
        } else if (planName > 20) {
            titleEl.css('font-size', '12px');
        } else if(planName > 10) {
            titleEl.css ('font-size', '15px');
        } 
    });
});

Try to click in the list itens. You see? As a response to "changing the unit", the title and font-size changes.

If this answer doesn't help you, give more details.

0
Zohaib Waqar On

This will work.TRy this

var planName = $("#title").text().length;

if(planName > 30) {
    $('#title').css("fontSize", "16px");
}else{ if(planName > 20) {
    $("#title").css("fontSize", "12px");
}else if(planName > 8) {
    $("#title").css("fontSize","24px")
}
7
Jeff Clarke On

I might do this with a combination of a bit of CSS to prevent the text from wrapping, then I would use some script to measure the length of the rendered text. If it's longer than whatever your predetermined maximum width is, use the script to apply a CSS transform.

#title {
  white-space: nowrap;
  display: inline-block; /* necessary for the scale to actually work */
  transform-origin: 0% 100%; /* set transform origin to bottom left corner of the title element */
}

.maxwidth-container {
  width: 400px;
}

Then in your script:

var scaleTitle = function() {

  var $title = $("#title");
  var maxWidth = $(".maxwidth-container").width();
  $title.css("transform","scale(1,1)"); //reset to normal scale in order to measure natural width

  if ($title.width() > maxWidth) {
    var scaleAmt = maxWidth / $title.width();
    $title.css("transform" , "scale(" + scaleAmt + "," + scaleAmt + ")");
  }

};

In your case, I have wrapped your #title element in a container that dictates the maximum size, but you could use an explicit set amount.

Call this function every time the user selects a home.

Example here: https://jsfiddle.net/9uvpun5o/5/