tags:

views:

3360

answers:

3

I need to display user entered text into a fixed size div. What i want is for the font size to be automatically adjusted so that the text fills the box as much as possible.

So - If the div is 400px x 300px. If someone enters ABC then it's really big font. If they enter a paragraph, then it would be a tiny font.

I'd probably want to start with a maximum font size - maybe 32px, and while the text is too big to fit the container, shrink the font size until it fits.

+1  A: 

This probably isn't very elegant, but maybe we can refine it together:

<html>
<head>
<style type="text/css">
    #dynamicDiv
    {
 background: #CCCCCC;
 width: 300px;
 height: 100px;
 font-size: 64px;
 overflow: hidden;
    }
</style>

<script type="text/javascript">
    function shrink()
    {
     var textSpan = document.getElementById("dynamicSpan");
     var textDiv = document.getElementById("dynamicDiv");

     textSpan.style.fontSize = 64;

     while(textSpan.offsetHeight > textDiv.offsetHeight)
     {
      textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
     }
    }
</script>

</head>
<body onload="shrink()">
    <div id="dynamicDiv"><span id="dynamicSpan">DYNAMIC FONT</span></div>
</body>
</html>
attack
+4  A: 

Thanks Attack. I wanted to use jQuery. You pointed me in the right direction, and this is what I ended up with:

;(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 });
});

and my html is like this

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

This is my first jquery plugin, so it's probably not as good as it should be. Pointers are certainly welcome.

GeekyMonkey
I actually just cleaned it up and packaged it as a plugin available from jquery.com at http://plugins.jquery.com/project/TextFill
GeekyMonkey
A: 

This is based on what GeekyMonkey posted above, with some modifications.

; (function($) {
/**
* Resize inner element to fit the outer element
* @author Some modifications by Alexander Sandstorm
* @author Code based on earlier works by Russ Painter ([email protected])
* @version 0.2
*/
$.fn.textfill = function(options) {

    options = jQuery.extend({
        maxFontSize: null,
        minFontSize: 8,
        step: 1
    }, options);

    return this.each(function() {

        var innerElements = $(this).children(':visible'),
            fontSize = options.maxFontSize || innerElements.css("font-size"), // use current font-size by default
            maxHeight = $(this).height(),
            maxWidth = $(this).width(),
            innerHeight,
            innerWidth;

        do {

            innerElements.css('font-size', fontSize);

            // use the combined height of all children, eg. multiple <p> elements.
            innerHeight = $.map(innerElements, function(e) {
                return $(e).outerHeight();
            }).reduce(function(p, c) {
                return p + c;
            }, 0);

            innerWidth = innerElements.outerWidth(); // assumes that all inner elements have the same width
            fontSize = fontSize - options.step;

        } while ((innerHeight > maxHeight || innerWidth > maxWidth) && fontSize > options.minFontSize);

    });

};

})(jQuery);
sandstrom
difference is that it can take multiple child elements, and that it takes padding into account. Uses font-size as the default maximum size, to avoid mixing javascript and css.
sandstrom