Reputation: 52977
How to calculate the font-size required for a text element to fill desired space? For example:
txt = "this text should fill the div precisely"
el = $("<div/>")
.html(txt)
.width(200)
.css({
fontFamily: "arial",
fontSize: font_size_to_fit(txt,"arial",200)
});
Edit: I am asking for a function that calculates the size based in a straighforward mathematical formula. It can be an approximation. The solution proposed on the question above is not correct because it involves an interactive DOM manipulation which is too heavy to be placed in a bottleneck area.
Upvotes: 2
Views: 5750
Reputation: 50787
I've never tried this, and perhaps it's crazy, but instead of all the (unfortunately unhelpful) suggestions to approach this by changing sizes over and over until the text fits, perhaps you could try just two very different font sizes (using no-wrap, of course) such as 10 and 100 and then interpolate or extrapolate your expected value assuming that the relationship should be nearly linear? I don't know if doing two layouts like this is too expensive for your bottleneck. If so, I'm not sure what hope you really have, as fonts can be tricky. But this might work.
Update: I've created a Fiddle using this technique. It seems to work reasonably well. The relevant code is:
var font_size_to_fit = (function() {
var $test = $("<span/>").appendTo("body").css({
visibility: "hidden",
border: 0,
padding: 0,
whiteSpace: "pre"
});
var minFont = 10, maxFont = 100;
return function(txt, fontFamily, size) {
$test.appendTo("body").css({fontFamily: fontFamily}).text(txt);
$test.css({fontSize: maxFont + "px"});
var maxWidth = $test.width();
$test.css({fontSize: minFont + "px"});
var minWidth = $test.width();
var width = (size - minWidth) * (maxFont - minFont) /
(maxWidth - minWidth) + minFont;
$test.detach();
return width + "px";
};
}());
This would probably also need some error-checking to ensure we have no division by zero, which would occur when minWidth == maxWidth
, most likely when the text supplied is empty. That's left as an exercise for the reader.
Another update: This broke at some point. I updated the Fiddle to include this:
return (width - .1) + "px";
This fixes an error noted in the comments. But I have no idea what has changed to make it break in between.
Upvotes: 3
Reputation: 9466
function font_size_to_fit(text, fontFamily, divSize) {
var tester = $("<div/>")
.appendTo("body")
.css({
position: "absolute",
left: "-9999px",
fontFamily: fontFamily })
.html(text);
var width;
var fontSize = 72;
do {
tester.css("fontSize", fontSize);
fontSize -= 1;
width = tester.width();
} while (!(width <= divSize && width >= divSize * .98));
return fontSize;
}
Maybe something like that? (Note: Doesn't address potential browser minimum font-sizes, didn't want to make the loop too complex.)
(Edited once to fix some potential bugs)
Upvotes: 2
Reputation: 10190
FitText.js is a great jQuery plugin for this.
It will resize fluidly (as the element changes size it will modify the font-size, not just on document ready or load), allows for min and max font sizes, and has some other options to allow you to tweak its behavior.
Upvotes: 2
Reputation: 57095
var x = 1;
var y = 20; //staring font-size
txt = "this text should fill the div precisely";
$('#element').html(txt).width(200).height(30).css('font-family', 'arial');
while (x == 1) {
var element = document.querySelector('#element');
if ((element.offsetHeight < element.scrollHeight) || (element.offsetWidth < element.scrollWidth)) {
element.style.background = "yellow";
element.style.fontSize = parseInt(y) + 'px';
y--;
} else {
x = 0;
element.style.background = "blue";
}
}
Upvotes: 1