Capagris
Capagris

Reputation: 3841

Checking a text element's width (based on font-size) against its parent container

I come to you with a tricky question:

Imagine you have the following basic structure:

<div><p>hello</p></div>

Now assume that div has display:block; and width:200px;. Using javascript, how would you check what font-size gives you a 'hello' as big as possible without horizontal overflow (in the case of one word) or jumping to a 2nd line in case of a sentence or group of words?

I can't think of a way to measure the space occupied by text so that it can then be checked against that of the parent container, let alone checking if an element is overflowing or linejumping.

If there is a way, I'm sure this is the right place to ask.

Upvotes: 8

Views: 3675

Answers (5)

Travis J
Travis J

Reputation: 82297

new jsFiddle Demo (updated 3/22/13)

I would just keep increasing the font size until the clientWidth or clientHeight changed. However, this becomes unreliable when using the actual element itself. To handle that situation, it is possible to create a span on the fly and then monitor the span's dimensions in order to properly retain the actual element's original sizes.

js

var adjuster = document.getElementById("adjust");
adjuster.onclick = function(){
 var p = document.getElementById("p");
 var text = p.innerText;
 var s = document.createElement("span");
 s.innerText = text;
 p.innerHTML = "";
 p.appendChild(s);
 var h = p.clientHeight;
 var w = p.clientWidth;
 var size = 10;
 while(true){
  size++;
  s.style.fontSize = size + "px";
  if($(s).height() > h || $(s).width() > w){
   size-=2;//rollback to no height change
   s.style.fontSize = size + "px";
   break;
  }
 }
 p.style.fontSize = s.style.fontSize;
 p.removeChild(s);
 p.innerText = text;
};

Upvotes: 0

SomeShinyObject
SomeShinyObject

Reputation: 7821

Quick and dirty

fiddle

Set p's style to display: inline then run this

var dWidth = $("div").width();
var pWidth = $("p").width();
var starting = 1;
while (pWidth < dWidth) {
    $("p").css("font-size",starting+"em");
    pWidth = $("p").width();
    starting = starting + .1;
}

Upvotes: 1

Explosion Pills
Explosion Pills

Reputation: 191789

There may be a method that's not as crazy, but this should be as precise as possible. Essentially, you have a div that you use to measure its width and incrementally increase the text content until it exceeds the width of the target div. Then, change the target div's <p>'s font size to the measuring div's minus 1:

http://jsfiddle.net/ExplosionPIlls/VUfAw/

var $measurer = $("<div>").css({
    position: 'fixed',
    top: '100%'
}).attr('id', 'measurer');
$measurer.append($("<p>").text($("p").text()));
$measurer.appendTo("body");

while ($measurer.width() <= $("#content").width()) {
    $("#measurer p").css('font-size', '+=1px');
    console.log($("#measurer").width());
}
$("#measurer p").css('font-size', '-=1px');
$("#content p").css('font-size', $("#measurer p").css('font-size'));
$measurer.remove();

Upvotes: 2

Alex
Alex

Reputation: 2800

Try this:

Auto-size dynamic text to fill fixed size container

(function($) {
    $.fn.textfill = function(options) {
        var fontSize = options.maxFontPixels;
        var ourText = $('span:visible:first', this);
        var maxHeight = $(this).height();
        var maxWidth = $(this).width();
        var textHeight;
        var textWidth;
        do {
            ourText.css('font-size', fontSize);
            textHeight = ourText.height();
            textWidth = ourText.width();
            fontSize = fontSize - 1;
        } while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
        return this;
    }
})(jQuery);

$(document).ready(function() {
    $('.jtextfill').textfill({ maxFontPixels: 36 });
});

<div class='jtextfill' style='width:100px;height:50px;'>
    <span>My Text Here</span>
</div>

Upvotes: 0

CTS_AE
CTS_AE

Reputation: 14893

Take a look at FitText

It is open source on github as well.

If you are interested in typography you might want to check out their other project called Lettering.js

Upvotes: 4

Related Questions