Fit title to div
Fits text by scaling font to a div with a fixed width and, most importantly, height.
by b9chris
HTML
<button>Resize</button>
<div class=event>RED</div>
<div class=event>Reasonably long thing</div>
<div class=event>Unreasonably, super long ridiculous maximum overdrive family event time home weightless edition thing</div>
<div class=event>Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really? Really?</div>
<div id=output></div>
CSS
body {
font: 10pt Verdana;
}
div.event {
/* height MUST be set for this to work! */
width: 300px; height: 100px;
background: #eee;
margin: 0 0 5px 0;
}
JavaScript
(function($, undefined) {
function resizeLoop(testTag, checkSize) {
var fontSize = 10;
var min = 10;
var max = 0;
var exceeded = false;
for(var i = 0; i < 30; i++) {
testTag.css('font-size', fontSize);
if (checkSize(testTag)) {
max = fontSize;
fontSize = (fontSize + min) / 2;
} else {
if (max == 0) {
// Start by growing exponentially
min = fontSize;
fontSize *= 2;
} else {
// If we're within 1px of max anyway, call it a day
if (max - fontSize < 2)
break;
// If we've seen a max, move half way to it
min = fontSize;
fontSize = (fontSize + max) / 2;
}
}
}
return fontSize;
}
function sizeText(tag) {
var width = tag.width();
var height = tag.height();
// Clone original tag and append to the same place so we keep its original styles, especially font
var testTag = tag.clone(true)
.appendTo(tag.parent())
.css({
position: 'absolute',
left: 0, top: 0,
width: 'auto', height: 'auto'
});
var fontSize;
// TODO: This decision of 10 characters is arbitrary. Come up
// with a smarter decision basis.
if (tag.text().length < 10) {
fontSize = resizeLoop(testTag, function(t) {
return t.width() > width || t.height() > height;
});
} else {
testTag.css('width', width);
fontSize = resizeLoop(testTag, function(t) {
return t.height() > height;
});
}
testTag.remove();
tag.css('font-size', fontSize);
$('#output').append('<div>' + fontSize +'</div>');
};
$.fn.fitText = function() {
this.each(function(i, tag) {
sizeText($(tag));
});
};
})(window.jQuery);
(function() {
$('button').click(function() {
$('div.event').fitText();
});
})();