I'm looking for a solution that will automatically re-size some text in a fixed width div to fit.
The only tricky thing is that on some of them, I need the both of the font sizes to match the smallest size (to ensure that both of the elements are always the same size.) I was thinking this could be achieved by giving them the same class name or something to indicate correlation.
Thanks!
So, given a bunch of inputs and outputs:
<div class="inputs">
<input type="text" value="John Smith">
<input type="text" value="Jane Doe">
</div>
<ul class="outputs">
<li></li>
<li></li>
</ul>
Use this function to bind the outputs to the inputs:
function sync( inputs, outputs ) {
var max_width, max_size, curr_size;
function curr_max_width() {
return Math.max.apply( null, $( outputs ).map( function () {
return $( this ).width();
}).get() );
}
outputs = $( outputs ).wrapInner( '<span />' ).children().get();
max_width = $( outputs ).parent().width();
max_size = parseInt( $( outputs ).css( 'font-size' ), 10 );
$( inputs ).bind( 'keyup change', function ( e ) {
$( outputs ).text( function ( i ) {
return $( inputs ).eq( i ).val();
});
curr_size = 0;
do {
curr_size += 1;
$( outputs ).css({ 'font-size': curr_size + 'px' });
} while ( curr_max_width() < max_width && curr_size < max_size );
$( outputs ).css({ 'font-size': ( curr_size - 1 ) + 'px' });
}).triggerHandler( 'change' );
}
Usage:
var inputs = $( 'input:text', '.inputs' ).get();
var outputs = $( 'li', '.outputs' ).get();
sync( inputs, outputs );
Live demo: http://jsfiddle.net/HF4W4/18/
So, the sync
function expects an array of <input>
elements as the first argument and an array of block elements as the second argument. Notice that the output elements should have white-space: nowrap
set. The sync
function inner-wraps the output elements in <span>
elements, so that it can read the width of the content.