我需要显示用户输入的文本到一个固定大小的div。我想要的是字体大小自动调整,以便文本尽可能多地填充框。

如果div是400px x 300px。如果有人输入ABC,那么字体就很大。如果他们输入一个段落,那么它将是一个很小的字体。

我可能想要从最大字体大小开始——可能是32px,当文本太大而不适合容器时,缩小字体大小直到它适合。


当前回答

这是我对OP的答案的修改。

简而言之,许多尝试优化此功能的人抱怨使用了循环。是的,虽然循环可能很慢,但其他方法可能不准确。

因此,我的方法是使用二进制搜索来找到最好的字体大小:

$.fn.textfill = function()
{
    var self = $(this);
    var parent = self.parent();

    var attr = self.attr('max-font-size');
    var maxFontSize = parseInt(attr, 10);
    var unit = attr.replace(maxFontSize, "");

    var minFontSize = parseInt(self.attr('min-font-size').replace(unit, ""));
    var fontSize = (maxFontSize + minFontSize) / 2;

    var maxHeight = parent.height();
    var maxWidth = parent.width();

    var textHeight;
    var textWidth;

    do
    {
        self.css('font-size', fontSize + unit);

        textHeight = self.height();
        textWidth = self.width();

        if(textHeight > maxHeight || textWidth > maxWidth)
        {
            maxFontSize = fontSize;
            fontSize = Math.floor((fontSize + minFontSize) / 2);
        }
        else if(textHeight < maxHeight || textWidth < maxWidth)
        {
            minFontSize = fontSize;
            fontSize = Math.floor((fontSize + maxFontSize) / 2);
        }
        else
            break;

    }
    while(maxFontSize - minFontSize > 1 && maxFontSize > minFontSize);

    self.css('font-size', fontSize + unit);

    return this;
}

function resizeText()
{
  $(".textfill").textfill();
}

$(document).ready(resizeText);
$(window).resize(resizeText);

这也允许元素指定最小和最大字体:

<div class="container">
    <div class="textfill" min-font-size="10px" max-font-size="72px">
        Text that will fill the container, to the best of its abilities, and it will <i>never</i> have overflow.
    </div>
</div>

此外,该算法是无单位的。你可以指定em, rem, %等,它将使用它的最终结果。

这是小提琴:https://jsfiddle.net/fkhqhnqe/1/

其他回答

我确实喜欢

let name = "Making statements based on opinion; back them up with references or personal experience."
let originFontSize = 15;
let maxDisplayCharInLine = 50; 
let fontSize = Math.min(originFontSize, originFontSize / (name.length / maxDisplayCharInLine));

这是基于GeekyMonkey上面发布的内容,并进行了一些修改。

; (function($) {
/**
* Resize inner element to fit the outer element
* @author Some modifications by Sandstrom
* @author Code based on earlier works by Russ Painter (WebDesign@GeekyMonkey.com)
* @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);

我从Marcus Ekwall: https://gist.github.com/3945316中分叉了上面的脚本,并根据我的喜好进行了调整,现在它会在窗口调整大小时触发,这样孩子就总是适合它的容器。我把脚本粘贴在下面以供参考。

(function($) {
    $.fn.textfill = function(maxFontSize) {
        maxFontSize = parseInt(maxFontSize, 10);
        return this.each(function(){
            var ourText = $("span", this);
            function resizefont(){
                var parent = ourText.parent(),
                maxHeight = parent.height(),
                maxWidth = parent.width(),
                fontSize = parseInt(ourText.css("fontSize"), 10),
                multiplier = maxWidth/ourText.width(),
                newSize = (fontSize*(multiplier));
                ourText.css("fontSize", maxFontSize > 0 && newSize > maxFontSize ? maxFontSize : newSize );
            }
            $(window).resize(function(){
                resizefont();
            });
            resizefont();
        });
    };
})(jQuery);

我的网站也遇到了同样的问题。我有一个页面,显示在投影仪上,在墙上,大屏幕上。

因为我不知道我的字体的最大大小,我重新使用了@GeekMonkey上面的插件,但增加了字体大小:

$.fn.textfill = function(options) {
        var defaults = { innerTag: 'span', padding: '10' };
        var Opts = jQuery.extend(defaults, options);

        return this.each(function() {
            var ourText = $(Opts.innerTag + ':visible:first', this);
            var fontSize = parseFloat(ourText.css('font-size'),10);
            var doNotTrepass = $(this).height()-2*Opts.padding ;
            var textHeight;

            do {
                ourText.css('font-size', fontSize);
                textHeight = ourText.height();
                fontSize = fontSize + 2;
            } while (textHeight < doNotTrepass );
        });
    };

大多数其他答案使用循环来减少字体大小,直到它适合div,这是非常缓慢的,因为页面需要重新渲染元素每次字体改变大小。我最终不得不编写自己的算法,使它能够定期更新内容,而不会冻结用户浏览器。我添加了一些其他功能(旋转文本,添加填充),并将其打包为jQuery插件,你可以在:

https://github.com/DanielHoffmann/jquery-bigtext

简单的电话

$("#text").bigText();

它会非常适合你的容器。

在这里看到它的行动:

http://danielhoffmann.github.io/jquery-bigtext/

现在它有一些限制,div必须有固定的高度和宽度,它不支持将文本包装成多行。

我将努力获得一个选项来设置最大字体大小。

编辑:我发现了更多的问题与插件,它不处理其他盒子模型除了标准的和div不能有边缘或边界。我会努力的。

Edit2:我现在已经修复了这些问题和限制,并添加了更多选项。你可以设置最大字体大小,你也可以选择限制字体大小使用宽度,高度或两者。我将在包装器元素中接受max-width和max-height值。

Edit3:我已经将插件更新到1.2.0版本。对代码和新选项(verticalAlign, horizontalAlign, textAlign)进行了重大清理,并支持span标签内的内部元素(如换行或字体很棒的图标)。