Search code examples
jquerycssfixed-width

Dynamic font-resizing for fixed width element that corresponds with another div


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!


Solution

  • 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.