自动大小的动态文本填充固定大小的容器

时间:2022-02-26 21:26:50

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.

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

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.

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

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.

我可能想从最大字体大小开始——可能是32px,虽然文本太大了,无法容纳容器,但是缩小字体大小直到适合。

18 个解决方案

#1


158  

Thanks Attack. I wanted to use jQuery.

由于攻击。我想用jQuery。

You pointed me in the right direction, and this is what I ended up with:

你给我指明了正确的方向,这就是我最后得出的结论:

Here is a link to the plugin: https://plugins.jquery.com/textfill/
And a link to the source: http://jquery-textfill.github.io/

这里有一个到插件的链接:https://plugins.jquery.com/textfill/和一个到源的链接:http://jquerytextfill.github.io/

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

我的html是这样的

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

这是我的第一个jquery插件,所以它可能没有它应有的那么好。指针肯定是受欢迎的。

#2


51  

I didn't find any of the previous solutions to be adequate enough due to bad performance, so I made my own that uses simple math instead of looping. Should work fine in all browsers as well.

由于性能不好,我没有找到任何以前的解决方案,所以我用简单的数学代替了循环。在所有浏览器中也应该运行良好。

According to this performance test case it is much faster then the other solutions found here.

根据这个性能测试用例,它比这里的其他解决方案要快得多。

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

If you want to contribute I've added this to Gist.

如果你想投稿,我已经把它添加到Gist中了。

#3


31  

Most of the other answers use a loop to reduce the font-size until it fits on the div, this is VERY slow since the page needs to re-render the element each time the font changes size. I eventually had to write my own algorithm to make it perform in a way that allowed me to update its contents periodically without freezing the user browser. I added some other functionality (rotating text, adding padding) and packaged it as a jQuery plugin, you can get it at:

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

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

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

simply call

简单的电话

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

and it will fit nicely on your container.

它很适合你的容器。

See it in action here:

在这里可以看到它的行动:

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

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

For now it has some limitations, the div must have a fixed height and width and it does not support wrapping text into multiple lines.

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

I will work on getting an option to set the maximum font-size.

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

Edit: I have found some more problems with the plugin, it does not handle other box-model besides the standard one and the div can't have margins or borders. I will work on it.

编辑:我发现这个插件还有一些问题,除了标准的盒子模型外,它不能处理其他的盒子模型,div不能有边距或边框。我会努力的。

Edit2: I have now fixed those problems and limitations and added more options. You can set maximum font-size and you can also choose to limit the font-size using either width, height or both. I will work into accepting a max-width and max-height values in the wrapper element.

我现在已经修正了这些问题和限制,并增加了更多的选项。您可以设置最大字体大小,也可以选择使用宽度、高度或两者都限制字体大小。我将在包装器元素中接受最大宽度和最大高度值。

Edit3: I have updated the plugin to version 1.2.0. Major cleanup on the code and new options (verticalAlign, horizontalAlign, textAlign) and support for inner elements inside the span tag (like line-breaks or font-awesome icons.)

我已经将插件升级到1.2.0版本。代码和新选项(垂直对齐、水平对齐、textAlign)的主要清理工作,以及对span标记内部元素的支持(比如换行符或字体很棒的图标)。

#4


30  

As much as I love the occasional upvotes I get for this answer (thanks!), this is really not the greatest approach to this problem. Please check out some of the other wonderful answers here, especially the ones that have found solutions without looping.

尽管我很喜欢这个答案(谢谢!),但这并不是解决这个问题的最好办法。请在这里查看其他一些精彩的答案,特别是那些已经找到了没有循环的解决方案的。


Still, for the sake of reference, here's my original answer:

不过,为了便于参考,以下是我最初的答案:

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

And here's a version with classes:

这是一个有类的版本:

<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 textDivs = document.getElementsByClassName("dynamicDiv");
        var textDivsLength = textDivs.length;

        // Loop through all of the dynamic divs on the page
        for(var i=0; i<textDivsLength; i++) {

            var textDiv = textDivs[i];

            // Loop through all of the dynamic spans within the div
            var textSpan = textDiv.getElementsByClassName("dynamicSpan")[0];

            // Use the same looping logic as before
            textSpan.style.fontSize = 64;

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

        }

    }
</script>

</head>
<body onload="shrink()">
    <div class="dynamicDiv"><span class="dynamicSpan">DYNAMIC FONT</span></div>
    <div class="dynamicDiv"><span class="dynamicSpan">ANOTHER DYNAMIC FONT</span></div>
    <div class="dynamicDiv"><span class="dynamicSpan">AND YET ANOTHER DYNAMIC FONT</span></div>
</body>
</html>

#5


9  

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

这是基于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);

#6


6  

I've created a directive for AngularJS - heavely inspired by GeekyMonkey's answer but without the jQuery dependency.

我为AngularJS创建了一个指令——灵感来自GeekyMonkey的答案,但没有jQuery依赖。

Demo: http://plnkr.co/edit/8tPCZIjvO3VSApSeTtYr?p=preview

演示:http://plnkr.co/edit/8tPCZIjvO3VSApSeTtYr?p=preview

Markup

标记

<div class="fittext" max-font-size="50" text="Your text goes here..."></div>

Directive

指令

app.directive('fittext', function() {

  return {
    scope: {
      minFontSize: '@',
      maxFontSize: '@',
      text: '='
    },
    restrict: 'C',
    transclude: true,
    template: '<div ng-transclude class="textContainer" ng-bind="text"></div>',
    controller: function($scope, $element, $attrs) {
      var fontSize = $scope.maxFontSize || 50;
      var minFontSize = $scope.minFontSize || 8;

      // text container
      var textContainer = $element[0].querySelector('.textContainer');

      angular.element(textContainer).css('word-wrap', 'break-word');

      // max dimensions for text container
      var maxHeight = $element[0].offsetHeight;
      var maxWidth = $element[0].offsetWidth;

      var textContainerHeight;
      var textContainerWidth;      

      var resizeText = function(){
        do {
          // set new font size and determine resulting dimensions
          textContainer.style.fontSize = fontSize + 'px';
          textContainerHeight = textContainer.offsetHeight;
          textContainerWidth = textContainer.offsetWidth;

          // shrink font size
          var ratioHeight = Math.floor(textContainerHeight / maxHeight);
          var ratioWidth = Math.floor(textContainerWidth / maxWidth);
          var shrinkFactor = ratioHeight > ratioWidth ? ratioHeight : ratioWidth;
          fontSize -= shrinkFactor;

        } while ((textContainerHeight > maxHeight || textContainerWidth > maxWidth) && fontSize > minFontSize);        
      };

      // watch for changes to text
      $scope.$watch('text', function(newText, oldText){
        if(newText === undefined) return;

        // text was deleted
        if(oldText !== undefined && newText.length < oldText.length){
          fontSize = $scope.maxFontSize;
        }
        resizeText();
      });
    }
  };
});

#7


6  

Here's an improved looping method that uses binary search to find the largest possible size that fits into the parent in the fewest steps possible (this is faster and more accurate than stepping by a fixed font size). The code is also optimized in several ways for performance.

这里有一种改进的循环方法,它使用二进制搜索以尽可能少的步骤找到适合父类的最大可能的大小(这比按固定的字体大小步进更快、更准确)。代码还通过几种方式进行了性能优化。

By default, 10 binary search steps will be performed, which will get within 0.1% of the optimal size. You could instead set numIter to some value N to get within 1/2^N of the optimal size.

默认情况下,将执行10个二进制搜索步骤,这将在最佳大小的0.1%以内。你可以设置numIter 1/2内一些值N ^ N的最佳大小。

Call it with a CSS selector, e.g.: fitToParent('.title-span');

使用CSS选择器调用它,例如:fitToParent('. titlespan ');

/**
 * Fit all elements matching a given CSS selector to their parent elements'
 * width and height, by adjusting the font-size attribute to be as large as
 * possible. Uses binary search.
 */
var fitToParent = function(selector) {
    var numIter = 10;  // Number of binary search iterations
    var regexp = /\d+(\.\d+)?/;
    var fontSize = function(elem) {
        var match = elem.css('font-size').match(regexp);
        var size = match == null ? 16 : parseFloat(match[0]);
        return isNaN(size) ? 16 : size;
    }
    $(selector).each(function() {
        var elem = $(this);
        var parentWidth = elem.parent().width();
        var parentHeight = elem.parent().height();
        if (elem.width() > parentWidth || elem.height() > parentHeight) {
            var maxSize = fontSize(elem), minSize = 0.1;
            for (var i = 0; i < numIter; i++) {
                var currSize = (minSize + maxSize) / 2;
                elem.css('font-size', currSize);
                if (elem.width() > parentWidth || elem.height() > parentHeight) {
                    maxSize = currSize;
                } else {
                    minSize = currSize;
                }
            }
            elem.css('font-size', minSize);
        }
    });
};

#8


5  

I forked the script above from Marcus Ekwall: https://gist.github.com/3945316 and tweaked it to my preferences, it now fires when the window is resized, so that the child always fits its container. I've pasted the script below for reference.

我在上面的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);

#9


4  

Here's my modification of the OP's answer.

这是我对OP答案的修改。

In short, many people who tried to optimize this complained that a loop was being used. Yes, while loops can be slow, other approaches can be inaccurate.

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

Therefore, my approach uses Binary Search to find the best Font Size:

因此,我的方法使用二分查找来找到最佳字体大小:

$.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);

This also allows the element to specify the minimum and maximum font:

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

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

Furthermore, this algorithm is unitless. You may specify em, rem, %, etc. and it will use that for its final result.

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

Here's the Fiddle: https://jsfiddle.net/fkhqhnqe/1/

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

#10


2  

I had exactly the same problem with my website. I have a page that is displayed on a projector, on walls, big screens..

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

As I don't know the max size of my font, I re-used the plugin above of @GeekMonkey but incrementing the fontsize :

由于我不知道字体的最大大小,我重新使用了@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 );
        });
    };

#11


1  

Here is a version of the accepted answer which can also take a minFontSize parameter.

下面是已接受的答案的一个版本,它也可以使用minFontSize参数。

(function($) {
    /**
    * Resizes an inner element's font so that the inner element completely fills the outer element.
    * @author Russ Painter WebDesign@GeekyMonkey.com
    * @author Blake Robertson 
    * @version 0.2 -- Modified it so a min font parameter can be specified.
    *    
    * @param {Object} Options which are maxFontPixels (default=40), innerTag (default='span')
    * @return All outer elements processed
    * @example <div class='mybigdiv filltext'><span>My Text To Resize</span></div>
    */
    $.fn.textfill = function(options) {
        var defaults = {
            maxFontPixels: 40,
            minFontPixels: 10,
            innerTag: 'span'
        };
        var Opts = jQuery.extend(defaults, options);
        return this.each(function() {
            var fontSize = Opts.maxFontPixels;
            var ourText = $(Opts.innerTag + ':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 > Opts.minFontPixels);
        });
    };
})(jQuery);

#12


1  

You can use FitText.js (github page) to solve this problem. Is really small and efficient compared to TextFill. TextFill uses an expensive while loop and FitText don't.

您可以使用FitText。js (github页面)解决这个问题。与TextFill相比,它非常小且高效。TextFill使用了一个昂贵的while循环,而FitText则没有。

Also FitText is more flexible (I use it in a proyect with very special requirements and works like a champ!).

FitText也更灵活(我将它用于非常特殊的需求,工作起来像冠军!)

HTML:

HTML:

<div class="container">
  <h1 id="responsive_headline">Your fancy title</h1>
</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jquery.fittext.js"></script>
<script>
  jQuery("#responsive_headline").fitText();
</script>

You also can set options to it:

你也可以为它设置选项:

<script>
  jQuery("#responsive_headline").fitText(1, { minFontSize: '30px', maxFontSize: '90px'});
</script>

CSS:

CSS:

#responsive_headline {
   width: 100%;
   display: block;
}

And if you need it, FitText also has a no-jQuery version.

如果需要的话,FitText也有一个非jquery版本。

#13


1  

EDIT: This code was used to show notes on top of a HTML5 video. It changes the font-size on the fly when the video is resized (when the browser window is resized.) The notes was connected to the video (just like notes on YouTube), which is why the code uses instances instead of a DOM handle directly.

编辑:这段代码用于在HTML5视频上显示注释。当视频被调整大小时(当浏览器窗口被调整大小时),它会动态地改变字体大小。这些注释与视频相连(就像YouTube上的注释),这就是为什么代码直接使用实例而不是DOM句柄。

As per request I'll throw in some code that I used to achieve this. (Text boxes over an HTML5 video.) The code was written a long time ago, and I quite frankly think it's pretty messy. Since the question is already answered and an answer is already accepted a long time ago I don't bother rewriting this. But if anyone wants to simplify this a bit, you're more than welcome!

根据请求,我将插入一些用于实现此目的的代码。(HTML5视频上的文本框)这段代码是很久以前写的,坦率地说,我认为它相当混乱。既然这个问题已经得到了回答,答案在很久以前就已经被接受了,我就不写了。但是如果有人想简化一下这个问题,你绝对是受欢迎的!

// Figure out the text size:
var text = val['text'];
var letters = text.length;
var findMultiplier = function(x) { // g(x)
    /* By analysing some functions with regression, the resulting function that
     gives the best font size with respect to the number of letters and the size
     of the note is:
     g(x) = 8.3 - 2.75x^0.15 [1 < x < 255]
     f(x) = g(letters) * (x / 1000)^0.5
     Font size = f(size)
     */
    return 8.3 - 2.75 * Math.pow(x, 0.15);
};

var findFontSize = function(x) { // f(x)
    return findMultiplier(letters) * Math.pow(x / 1000, 0.5);
};

val.setFontSizeListener = function() {
    p.style.fontSize = '1px'; // So the text should not overflow the box when measuring.
    var noteStyle = window.getComputedStyle(table);
    var width = noteStyle.getPropertyValue('width');
    var height = noteStyle.getPropertyValue('height');
    var size = width.substring(0, width.length - 2) * height.substring(0, height.length - 2);
    p.style.fontSize = findFontSize(size) + 'px';
};
window.addEventListener('resize', val.setFontSizeListener);

You'll probably need to tweak these numbers from font-family to font-family. A good way to do this is download a free graph visualizer called GeoGebra. Change the length of the text and the size of the box. Then you manually set the size. Plot the manual results into the coordinate system. Then you enter the two equations I've posted here and you tweak the numbers until "my" graph fits your own manually plotted points.

您可能需要调整这些数字从字体族到字体族。一个很好的方法是下载一个叫做GeoGebra的免费图形可视化工具。更改文本的长度和框的大小。然后手动设置大小。将手动结果绘制到坐标系统中。然后你输入我在这里贴出的两个方程,调整数字,直到“我的”图形符合你自己的手工绘制点。

#14


1  

The proposed iterative solutions can be sped up dramatically on two fronts:

提出的迭代解决方案可以在两个方面得到显著的加速:

1) Multiply the font size by some constant, rather than adding or subtracting 1.

1)将字体大小乘以某个常数,而不是加或减1。

2) First, zero in using a course constant, say, double the size each loop. Then, with a rough idea of where to start, do the same thing with a finer adjustment, say, multiply by 1.1. While the perfectionist might want the exact integer pixel size of the ideal font, most observers don't notice the difference between 100 and 110 pixels. If you are a perfectionist, then repeat a third time with an even finer adjustment.

2)首先,使用课程常数为零,例如,将每个循环的大小加倍。然后,大致了解从哪里开始,做同样的事情,进行更精细的调整,例如,乘以1.1。虽然完美主义者可能想要理想字体的整数像素大小,但大多数观察者并没有注意到100到110像素之间的差异。如果你是一个完美主义者,那么第三次再做一次更好的调整。

Rather than writing a specific routine or plug-in that answers the exact question, I just rely on the basic ideas and write variations of the code to handle all kinds of layout issues, not just text, including fitting divs, spans, images,... by width, height, area,... within a container, matching another element....

不是编写一个特定的例程或插件来回答确切的问题,我只是依靠基本的思想和编写代码的变体来处理各种布局问题,而不仅仅是文本,包括拟合div、span、images……宽度,高度,面积,……在一个容器中,匹配另一个元素....

Here's an example:

这里有一个例子:

  var                           nWindowH_px             = jQuery(window).height();
  var                           nWas                    = 0;
  var                           nTry                    = 5;

  do{
   nWas = nTry;
   nTry *= 2;
   jQuery('#divTitle').css('font-size' ,nTry +'px');
  }while( jQuery('#divTitle').height() < nWindowH_px );

  nTry = nWas;

  do{
   nWas = nTry;
   nTry = Math.floor( nTry * 1.1 );
   jQuery('#divTitle').css('font-size' ,nTry +'px');
  }while( nWas != nTry   &&   jQuery('#divTitle').height() < nWindowH_px );

  jQuery('#divTitle').css('font-size' ,nWas +'px');

#15


0  

i know this one is an oldie, but there are still people out there who need this functionality. i went with geekMonkey solution, but its whack. simply because its slow. what he does, is he adjusts the font size to maximum (maxFontPixels) and then checks, if it fits inside the container. else it reduces the font size by 1px and checks again. why not simply check the previous container for the height and submit that value?? (yeah, i know why, but i now made a solution, that only works on the height and also has a min/max option)

我知道这个功能已经过时了,但仍然有人需要这个功能。我用的是geekMonkey的解决方案,但是很糟糕。只是因为它的缓慢。他所做的是将字体大小调整为最大值(maxFontPixels),然后检查是否适合容器。否则,它将字体大小减少1px,并再次检查。为什么不简单地检查前一个容器的高度并提交这个值?(是的,我知道为什么,但我现在做了一个解决方案,它只适用于高度,并且有最小/最大值选项)

way quicker solution:

更快的解决方案:

var index_letters_resize;
(index_letters_resize = function() {
  $(".textfill").each(function() {
    var
      $this = $(this),
      height = Math.min( Math.max( parseInt( $this.height() ), 40 ), 150 );
    $this.find(".size-adjust").css({
      fontSize: height
    });
  });
}).call();

$(window).on('resize', function() {
  index_letters_resize();
);

and this would be the HTML:

这就是HTML

<div class="textfill">
  <span class="size-adjust">adjusted element</span>
  other variable stuff that defines the container size
</div>

again: this solution ONLY checks for the height of the container. that's why this function does not has to check, if the element fits inside. but i also implemented a min/max value (40min, 150max) so for me this works perfectly fine (and also works on window resize).

同样:此解决方案只检查容器的高度。这就是为什么这个函数不需要检查元素是否在里面。但是我也实现了一个最小值/最大值(40min, 150max),所以对我来说,这非常好(也适用于窗口大小)。

#16


0  

I got the same problem and the solution is basically use javascript to control font-size. Check this example on codepen:

我也遇到了同样的问题,解决方案基本上就是使用javascript来控制字体大小。在codepen上检查这个例子:

https://codepen.io/ThePostModernPlatonic/pen/BZKzVR

https://codepen.io/ThePostModernPlatonic/pen/BZKzVR

This is example is only for height, maybe you need to put some if's about the width.

这是一个高度的例子,也许你需要放一些if是关于宽度的。

try to resize it

尝试调整它

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento sem título</title>
<style>
</style>
</head>
<body>
<div style="height:100vh;background-color: tomato;" id="wrap">        
  <h1 class="quote" id="quotee" style="padding-top: 56px">Because too much "light" doesn't <em>illuminate</em> our paths and warm us, it only blinds and burns us.</h1>
</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
  var multiplexador = 3;
  initial_div_height = document.getElementById ("wrap").scrollHeight;
  setInterval(function(){ 
    var div = document.getElementById ("wrap");
    var frase = document.getElementById ("quotee");
    var message = "WIDTH div " + div.scrollWidth + "px. "+ frase.scrollWidth+"px. frase \n";
    message += "HEIGHT div " + initial_div_height + "px. "+ frase.scrollHeight+"px. frase \n";           
    if (frase.scrollHeight < initial_div_height - 30){
      multiplexador += 1;
      $("#quotee").css("font-size", multiplexador); 
    }
    console.log(message);          
  }, 10);
</script>
</html>

#17


0  

I did like

我也喜欢

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

#18


-1  

Here is another version of this solution:

这个解决方案的另一个版本是:

shrinkTextInElement : function(el, minFontSizePx) {
    if(!minFontSizePx) {
        minFontSizePx = 5;
    }
    while(el.offsetWidth > el.parentNode.offsetWidth || el.offsetHeight > el.parentNode.offsetHeight) {

        var newFontSize = (parseInt(el.style.fontSize, 10) - 3);
        if(newFontSize <= minFontSizePx) {
            break;
        }

        el.style.fontSize = newFontSize + "px";
    }
}

#1


158  

Thanks Attack. I wanted to use jQuery.

由于攻击。我想用jQuery。

You pointed me in the right direction, and this is what I ended up with:

你给我指明了正确的方向,这就是我最后得出的结论:

Here is a link to the plugin: https://plugins.jquery.com/textfill/
And a link to the source: http://jquery-textfill.github.io/

这里有一个到插件的链接:https://plugins.jquery.com/textfill/和一个到源的链接:http://jquerytextfill.github.io/

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

我的html是这样的

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

这是我的第一个jquery插件,所以它可能没有它应有的那么好。指针肯定是受欢迎的。

#2


51  

I didn't find any of the previous solutions to be adequate enough due to bad performance, so I made my own that uses simple math instead of looping. Should work fine in all browsers as well.

由于性能不好,我没有找到任何以前的解决方案,所以我用简单的数学代替了循环。在所有浏览器中也应该运行良好。

According to this performance test case it is much faster then the other solutions found here.

根据这个性能测试用例,它比这里的其他解决方案要快得多。

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

If you want to contribute I've added this to Gist.

如果你想投稿,我已经把它添加到Gist中了。

#3


31  

Most of the other answers use a loop to reduce the font-size until it fits on the div, this is VERY slow since the page needs to re-render the element each time the font changes size. I eventually had to write my own algorithm to make it perform in a way that allowed me to update its contents periodically without freezing the user browser. I added some other functionality (rotating text, adding padding) and packaged it as a jQuery plugin, you can get it at:

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

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

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

simply call

简单的电话

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

and it will fit nicely on your container.

它很适合你的容器。

See it in action here:

在这里可以看到它的行动:

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

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

For now it has some limitations, the div must have a fixed height and width and it does not support wrapping text into multiple lines.

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

I will work on getting an option to set the maximum font-size.

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

Edit: I have found some more problems with the plugin, it does not handle other box-model besides the standard one and the div can't have margins or borders. I will work on it.

编辑:我发现这个插件还有一些问题,除了标准的盒子模型外,它不能处理其他的盒子模型,div不能有边距或边框。我会努力的。

Edit2: I have now fixed those problems and limitations and added more options. You can set maximum font-size and you can also choose to limit the font-size using either width, height or both. I will work into accepting a max-width and max-height values in the wrapper element.

我现在已经修正了这些问题和限制,并增加了更多的选项。您可以设置最大字体大小,也可以选择使用宽度、高度或两者都限制字体大小。我将在包装器元素中接受最大宽度和最大高度值。

Edit3: I have updated the plugin to version 1.2.0. Major cleanup on the code and new options (verticalAlign, horizontalAlign, textAlign) and support for inner elements inside the span tag (like line-breaks or font-awesome icons.)

我已经将插件升级到1.2.0版本。代码和新选项(垂直对齐、水平对齐、textAlign)的主要清理工作,以及对span标记内部元素的支持(比如换行符或字体很棒的图标)。

#4


30  

As much as I love the occasional upvotes I get for this answer (thanks!), this is really not the greatest approach to this problem. Please check out some of the other wonderful answers here, especially the ones that have found solutions without looping.

尽管我很喜欢这个答案(谢谢!),但这并不是解决这个问题的最好办法。请在这里查看其他一些精彩的答案,特别是那些已经找到了没有循环的解决方案的。


Still, for the sake of reference, here's my original answer:

不过,为了便于参考,以下是我最初的答案:

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

And here's a version with classes:

这是一个有类的版本:

<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 textDivs = document.getElementsByClassName("dynamicDiv");
        var textDivsLength = textDivs.length;

        // Loop through all of the dynamic divs on the page
        for(var i=0; i<textDivsLength; i++) {

            var textDiv = textDivs[i];

            // Loop through all of the dynamic spans within the div
            var textSpan = textDiv.getElementsByClassName("dynamicSpan")[0];

            // Use the same looping logic as before
            textSpan.style.fontSize = 64;

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

        }

    }
</script>

</head>
<body onload="shrink()">
    <div class="dynamicDiv"><span class="dynamicSpan">DYNAMIC FONT</span></div>
    <div class="dynamicDiv"><span class="dynamicSpan">ANOTHER DYNAMIC FONT</span></div>
    <div class="dynamicDiv"><span class="dynamicSpan">AND YET ANOTHER DYNAMIC FONT</span></div>
</body>
</html>

#5


9  

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

这是基于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);

#6


6  

I've created a directive for AngularJS - heavely inspired by GeekyMonkey's answer but without the jQuery dependency.

我为AngularJS创建了一个指令——灵感来自GeekyMonkey的答案,但没有jQuery依赖。

Demo: http://plnkr.co/edit/8tPCZIjvO3VSApSeTtYr?p=preview

演示:http://plnkr.co/edit/8tPCZIjvO3VSApSeTtYr?p=preview

Markup

标记

<div class="fittext" max-font-size="50" text="Your text goes here..."></div>

Directive

指令

app.directive('fittext', function() {

  return {
    scope: {
      minFontSize: '@',
      maxFontSize: '@',
      text: '='
    },
    restrict: 'C',
    transclude: true,
    template: '<div ng-transclude class="textContainer" ng-bind="text"></div>',
    controller: function($scope, $element, $attrs) {
      var fontSize = $scope.maxFontSize || 50;
      var minFontSize = $scope.minFontSize || 8;

      // text container
      var textContainer = $element[0].querySelector('.textContainer');

      angular.element(textContainer).css('word-wrap', 'break-word');

      // max dimensions for text container
      var maxHeight = $element[0].offsetHeight;
      var maxWidth = $element[0].offsetWidth;

      var textContainerHeight;
      var textContainerWidth;      

      var resizeText = function(){
        do {
          // set new font size and determine resulting dimensions
          textContainer.style.fontSize = fontSize + 'px';
          textContainerHeight = textContainer.offsetHeight;
          textContainerWidth = textContainer.offsetWidth;

          // shrink font size
          var ratioHeight = Math.floor(textContainerHeight / maxHeight);
          var ratioWidth = Math.floor(textContainerWidth / maxWidth);
          var shrinkFactor = ratioHeight > ratioWidth ? ratioHeight : ratioWidth;
          fontSize -= shrinkFactor;

        } while ((textContainerHeight > maxHeight || textContainerWidth > maxWidth) && fontSize > minFontSize);        
      };

      // watch for changes to text
      $scope.$watch('text', function(newText, oldText){
        if(newText === undefined) return;

        // text was deleted
        if(oldText !== undefined && newText.length < oldText.length){
          fontSize = $scope.maxFontSize;
        }
        resizeText();
      });
    }
  };
});

#7


6  

Here's an improved looping method that uses binary search to find the largest possible size that fits into the parent in the fewest steps possible (this is faster and more accurate than stepping by a fixed font size). The code is also optimized in several ways for performance.

这里有一种改进的循环方法,它使用二进制搜索以尽可能少的步骤找到适合父类的最大可能的大小(这比按固定的字体大小步进更快、更准确)。代码还通过几种方式进行了性能优化。

By default, 10 binary search steps will be performed, which will get within 0.1% of the optimal size. You could instead set numIter to some value N to get within 1/2^N of the optimal size.

默认情况下,将执行10个二进制搜索步骤,这将在最佳大小的0.1%以内。你可以设置numIter 1/2内一些值N ^ N的最佳大小。

Call it with a CSS selector, e.g.: fitToParent('.title-span');

使用CSS选择器调用它,例如:fitToParent('. titlespan ');

/**
 * Fit all elements matching a given CSS selector to their parent elements'
 * width and height, by adjusting the font-size attribute to be as large as
 * possible. Uses binary search.
 */
var fitToParent = function(selector) {
    var numIter = 10;  // Number of binary search iterations
    var regexp = /\d+(\.\d+)?/;
    var fontSize = function(elem) {
        var match = elem.css('font-size').match(regexp);
        var size = match == null ? 16 : parseFloat(match[0]);
        return isNaN(size) ? 16 : size;
    }
    $(selector).each(function() {
        var elem = $(this);
        var parentWidth = elem.parent().width();
        var parentHeight = elem.parent().height();
        if (elem.width() > parentWidth || elem.height() > parentHeight) {
            var maxSize = fontSize(elem), minSize = 0.1;
            for (var i = 0; i < numIter; i++) {
                var currSize = (minSize + maxSize) / 2;
                elem.css('font-size', currSize);
                if (elem.width() > parentWidth || elem.height() > parentHeight) {
                    maxSize = currSize;
                } else {
                    minSize = currSize;
                }
            }
            elem.css('font-size', minSize);
        }
    });
};

#8


5  

I forked the script above from Marcus Ekwall: https://gist.github.com/3945316 and tweaked it to my preferences, it now fires when the window is resized, so that the child always fits its container. I've pasted the script below for reference.

我在上面的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);

#9


4  

Here's my modification of the OP's answer.

这是我对OP答案的修改。

In short, many people who tried to optimize this complained that a loop was being used. Yes, while loops can be slow, other approaches can be inaccurate.

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

Therefore, my approach uses Binary Search to find the best Font Size:

因此,我的方法使用二分查找来找到最佳字体大小:

$.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);

This also allows the element to specify the minimum and maximum font:

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

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

Furthermore, this algorithm is unitless. You may specify em, rem, %, etc. and it will use that for its final result.

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

Here's the Fiddle: https://jsfiddle.net/fkhqhnqe/1/

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

#10


2  

I had exactly the same problem with my website. I have a page that is displayed on a projector, on walls, big screens..

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

As I don't know the max size of my font, I re-used the plugin above of @GeekMonkey but incrementing the fontsize :

由于我不知道字体的最大大小,我重新使用了@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 );
        });
    };

#11


1  

Here is a version of the accepted answer which can also take a minFontSize parameter.

下面是已接受的答案的一个版本,它也可以使用minFontSize参数。

(function($) {
    /**
    * Resizes an inner element's font so that the inner element completely fills the outer element.
    * @author Russ Painter WebDesign@GeekyMonkey.com
    * @author Blake Robertson 
    * @version 0.2 -- Modified it so a min font parameter can be specified.
    *    
    * @param {Object} Options which are maxFontPixels (default=40), innerTag (default='span')
    * @return All outer elements processed
    * @example <div class='mybigdiv filltext'><span>My Text To Resize</span></div>
    */
    $.fn.textfill = function(options) {
        var defaults = {
            maxFontPixels: 40,
            minFontPixels: 10,
            innerTag: 'span'
        };
        var Opts = jQuery.extend(defaults, options);
        return this.each(function() {
            var fontSize = Opts.maxFontPixels;
            var ourText = $(Opts.innerTag + ':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 > Opts.minFontPixels);
        });
    };
})(jQuery);

#12


1  

You can use FitText.js (github page) to solve this problem. Is really small and efficient compared to TextFill. TextFill uses an expensive while loop and FitText don't.

您可以使用FitText。js (github页面)解决这个问题。与TextFill相比,它非常小且高效。TextFill使用了一个昂贵的while循环,而FitText则没有。

Also FitText is more flexible (I use it in a proyect with very special requirements and works like a champ!).

FitText也更灵活(我将它用于非常特殊的需求,工作起来像冠军!)

HTML:

HTML:

<div class="container">
  <h1 id="responsive_headline">Your fancy title</h1>
</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jquery.fittext.js"></script>
<script>
  jQuery("#responsive_headline").fitText();
</script>

You also can set options to it:

你也可以为它设置选项:

<script>
  jQuery("#responsive_headline").fitText(1, { minFontSize: '30px', maxFontSize: '90px'});
</script>

CSS:

CSS:

#responsive_headline {
   width: 100%;
   display: block;
}

And if you need it, FitText also has a no-jQuery version.

如果需要的话,FitText也有一个非jquery版本。

#13


1  

EDIT: This code was used to show notes on top of a HTML5 video. It changes the font-size on the fly when the video is resized (when the browser window is resized.) The notes was connected to the video (just like notes on YouTube), which is why the code uses instances instead of a DOM handle directly.

编辑:这段代码用于在HTML5视频上显示注释。当视频被调整大小时(当浏览器窗口被调整大小时),它会动态地改变字体大小。这些注释与视频相连(就像YouTube上的注释),这就是为什么代码直接使用实例而不是DOM句柄。

As per request I'll throw in some code that I used to achieve this. (Text boxes over an HTML5 video.) The code was written a long time ago, and I quite frankly think it's pretty messy. Since the question is already answered and an answer is already accepted a long time ago I don't bother rewriting this. But if anyone wants to simplify this a bit, you're more than welcome!

根据请求,我将插入一些用于实现此目的的代码。(HTML5视频上的文本框)这段代码是很久以前写的,坦率地说,我认为它相当混乱。既然这个问题已经得到了回答,答案在很久以前就已经被接受了,我就不写了。但是如果有人想简化一下这个问题,你绝对是受欢迎的!

// Figure out the text size:
var text = val['text'];
var letters = text.length;
var findMultiplier = function(x) { // g(x)
    /* By analysing some functions with regression, the resulting function that
     gives the best font size with respect to the number of letters and the size
     of the note is:
     g(x) = 8.3 - 2.75x^0.15 [1 < x < 255]
     f(x) = g(letters) * (x / 1000)^0.5
     Font size = f(size)
     */
    return 8.3 - 2.75 * Math.pow(x, 0.15);
};

var findFontSize = function(x) { // f(x)
    return findMultiplier(letters) * Math.pow(x / 1000, 0.5);
};

val.setFontSizeListener = function() {
    p.style.fontSize = '1px'; // So the text should not overflow the box when measuring.
    var noteStyle = window.getComputedStyle(table);
    var width = noteStyle.getPropertyValue('width');
    var height = noteStyle.getPropertyValue('height');
    var size = width.substring(0, width.length - 2) * height.substring(0, height.length - 2);
    p.style.fontSize = findFontSize(size) + 'px';
};
window.addEventListener('resize', val.setFontSizeListener);

You'll probably need to tweak these numbers from font-family to font-family. A good way to do this is download a free graph visualizer called GeoGebra. Change the length of the text and the size of the box. Then you manually set the size. Plot the manual results into the coordinate system. Then you enter the two equations I've posted here and you tweak the numbers until "my" graph fits your own manually plotted points.

您可能需要调整这些数字从字体族到字体族。一个很好的方法是下载一个叫做GeoGebra的免费图形可视化工具。更改文本的长度和框的大小。然后手动设置大小。将手动结果绘制到坐标系统中。然后你输入我在这里贴出的两个方程,调整数字,直到“我的”图形符合你自己的手工绘制点。

#14


1  

The proposed iterative solutions can be sped up dramatically on two fronts:

提出的迭代解决方案可以在两个方面得到显著的加速:

1) Multiply the font size by some constant, rather than adding or subtracting 1.

1)将字体大小乘以某个常数,而不是加或减1。

2) First, zero in using a course constant, say, double the size each loop. Then, with a rough idea of where to start, do the same thing with a finer adjustment, say, multiply by 1.1. While the perfectionist might want the exact integer pixel size of the ideal font, most observers don't notice the difference between 100 and 110 pixels. If you are a perfectionist, then repeat a third time with an even finer adjustment.

2)首先,使用课程常数为零,例如,将每个循环的大小加倍。然后,大致了解从哪里开始,做同样的事情,进行更精细的调整,例如,乘以1.1。虽然完美主义者可能想要理想字体的整数像素大小,但大多数观察者并没有注意到100到110像素之间的差异。如果你是一个完美主义者,那么第三次再做一次更好的调整。

Rather than writing a specific routine or plug-in that answers the exact question, I just rely on the basic ideas and write variations of the code to handle all kinds of layout issues, not just text, including fitting divs, spans, images,... by width, height, area,... within a container, matching another element....

不是编写一个特定的例程或插件来回答确切的问题,我只是依靠基本的思想和编写代码的变体来处理各种布局问题,而不仅仅是文本,包括拟合div、span、images……宽度,高度,面积,……在一个容器中,匹配另一个元素....

Here's an example:

这里有一个例子:

  var                           nWindowH_px             = jQuery(window).height();
  var                           nWas                    = 0;
  var                           nTry                    = 5;

  do{
   nWas = nTry;
   nTry *= 2;
   jQuery('#divTitle').css('font-size' ,nTry +'px');
  }while( jQuery('#divTitle').height() < nWindowH_px );

  nTry = nWas;

  do{
   nWas = nTry;
   nTry = Math.floor( nTry * 1.1 );
   jQuery('#divTitle').css('font-size' ,nTry +'px');
  }while( nWas != nTry   &&   jQuery('#divTitle').height() < nWindowH_px );

  jQuery('#divTitle').css('font-size' ,nWas +'px');

#15


0  

i know this one is an oldie, but there are still people out there who need this functionality. i went with geekMonkey solution, but its whack. simply because its slow. what he does, is he adjusts the font size to maximum (maxFontPixels) and then checks, if it fits inside the container. else it reduces the font size by 1px and checks again. why not simply check the previous container for the height and submit that value?? (yeah, i know why, but i now made a solution, that only works on the height and also has a min/max option)

我知道这个功能已经过时了,但仍然有人需要这个功能。我用的是geekMonkey的解决方案,但是很糟糕。只是因为它的缓慢。他所做的是将字体大小调整为最大值(maxFontPixels),然后检查是否适合容器。否则,它将字体大小减少1px,并再次检查。为什么不简单地检查前一个容器的高度并提交这个值?(是的,我知道为什么,但我现在做了一个解决方案,它只适用于高度,并且有最小/最大值选项)

way quicker solution:

更快的解决方案:

var index_letters_resize;
(index_letters_resize = function() {
  $(".textfill").each(function() {
    var
      $this = $(this),
      height = Math.min( Math.max( parseInt( $this.height() ), 40 ), 150 );
    $this.find(".size-adjust").css({
      fontSize: height
    });
  });
}).call();

$(window).on('resize', function() {
  index_letters_resize();
);

and this would be the HTML:

这就是HTML

<div class="textfill">
  <span class="size-adjust">adjusted element</span>
  other variable stuff that defines the container size
</div>

again: this solution ONLY checks for the height of the container. that's why this function does not has to check, if the element fits inside. but i also implemented a min/max value (40min, 150max) so for me this works perfectly fine (and also works on window resize).

同样:此解决方案只检查容器的高度。这就是为什么这个函数不需要检查元素是否在里面。但是我也实现了一个最小值/最大值(40min, 150max),所以对我来说,这非常好(也适用于窗口大小)。

#16


0  

I got the same problem and the solution is basically use javascript to control font-size. Check this example on codepen:

我也遇到了同样的问题,解决方案基本上就是使用javascript来控制字体大小。在codepen上检查这个例子:

https://codepen.io/ThePostModernPlatonic/pen/BZKzVR

https://codepen.io/ThePostModernPlatonic/pen/BZKzVR

This is example is only for height, maybe you need to put some if's about the width.

这是一个高度的例子,也许你需要放一些if是关于宽度的。

try to resize it

尝试调整它

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento sem título</title>
<style>
</style>
</head>
<body>
<div style="height:100vh;background-color: tomato;" id="wrap">        
  <h1 class="quote" id="quotee" style="padding-top: 56px">Because too much "light" doesn't <em>illuminate</em> our paths and warm us, it only blinds and burns us.</h1>
</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
  var multiplexador = 3;
  initial_div_height = document.getElementById ("wrap").scrollHeight;
  setInterval(function(){ 
    var div = document.getElementById ("wrap");
    var frase = document.getElementById ("quotee");
    var message = "WIDTH div " + div.scrollWidth + "px. "+ frase.scrollWidth+"px. frase \n";
    message += "HEIGHT div " + initial_div_height + "px. "+ frase.scrollHeight+"px. frase \n";           
    if (frase.scrollHeight < initial_div_height - 30){
      multiplexador += 1;
      $("#quotee").css("font-size", multiplexador); 
    }
    console.log(message);          
  }, 10);
</script>
</html>

#17


0  

I did like

我也喜欢

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

#18


-1  

Here is another version of this solution:

这个解决方案的另一个版本是:

shrinkTextInElement : function(el, minFontSizePx) {
    if(!minFontSizePx) {
        minFontSizePx = 5;
    }
    while(el.offsetWidth > el.parentNode.offsetWidth || el.offsetHeight > el.parentNode.offsetHeight) {

        var newFontSize = (parseInt(el.style.fontSize, 10) - 3);
        if(newFontSize <= minFontSizePx) {
            break;
        }

        el.style.fontSize = newFontSize + "px";
    }
}