我需要显示用户输入的文本到一个固定大小的div。我想要的是字体大小自动调整,以便文本尽可能多地填充框。
如果div是400px x 300px。如果有人输入ABC,那么字体就很大。如果他们输入一个段落,那么它将是一个很小的字体。
我可能想要从最大字体大小开始——可能是32px,当文本太大而不适合容器时,缩小字体大小直到它适合。
我需要显示用户输入的文本到一个固定大小的div。我想要的是字体大小自动调整,以便文本尽可能多地填充框。
如果div是400px x 300px。如果有人输入ABC,那么字体就很大。如果他们输入一个段落,那么它将是一个很小的字体。
我可能想要从最大字体大小开始——可能是32px,当文本太大而不适合容器时,缩小字体大小直到它适合。
当前回答
我从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);
其他回答
下面是接受的答案的一个版本,它也可以接受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);
下面是这个解决方案的另一个版本:
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";
}
}
大多数其他答案使用循环来减少字体大小,直到它适合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标签内的内部元素(如换行或字体很棒的图标)。
你可以使用FitText.js (github页面)来解决这个问题。与TextFill相比是非常小和有效的。TextFill使用了昂贵的while循环,而FitText没有。
FitText也更灵活(我在一个有非常特殊要求的项目中使用它,工作起来像个冠军!)。
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>
你也可以设置选项:
<script>
jQuery("#responsive_headline").fitText(1, { minFontSize: '30px', maxFontSize: '90px'});
</script>
CSS:
#responsive_headline {
width: 100%;
display: block;
}
如果你需要它,FitText也有一个非jquery版本。
只是想增加我的内容表版本。
$.fn.fitInText = function() { this.each(function() { let textbox = $(this); let textboxNode = this; let mutationCallback = function(mutationsList, observer) { if (observer) { observer.disconnect(); } textbox.css('font-size', 0); let desiredHeight = textbox.css('height'); for (i = 12; i < 50; i++) { textbox.css('font-size', i); if (textbox.css('height') > desiredHeight) { textbox.css('font-size', i - 1); break; } } var config = { attributes: true, childList: true, subtree: true, characterData: true }; let newobserver = new MutationObserver(mutationCallback); newobserver.observe(textboxNode, config); }; mutationCallback(); }); } $('#inner').fitInText(); #outer { display: table; width: 100%; } #inner { border: 1px solid black; height: 170px; text-align: center; display: table-cell; vertical-align: middle; word-break: break-all; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="outer"> <div id="inner" contenteditable=true> TEST </div> </div>