调整字体大小以适合div(在一行上)

TCC*_*CCV 62 css jquery

已经提出了类似的问题,但解决方案确实与我想要做的事情相吻合.基本上,我有一篇标题(<h1>)的文章.我不想控制标题的长度,但我也不希望标题出现在多行上.有没有办法用css或jQuery根据<div>标签的宽度调整文本大小?

我知道如果我能检测到文本与边缘的重叠,我会用伪代码做什么<div>:

var fontize = $("#title").css("font-size");
var i = /*remove unit from integer*/
while( /*text overlaps div*/ ){
    $("#title").css("font-size", --i+"pt");
}
Run Code Online (Sandbox Code Playgroud)

如果有一个CSS属性我可以设置更好,但我似乎找不到一个(溢出在这种情况下不起作用).

Rob*_*nik 46

CSS不,Javascript是的

使用CSS无法做到这一点,但你可以在javascript/jQuery中完成.为了帮助您使用伪代码,因为您已经知道该怎么做.只是你不知道如何检测多余的宽度.

最好的方法是让DIV具有以下(至少)风格:

position: absolute;
visibility: hidden;
white-space: nowrap;
font-family: /* same as your title's */
Run Code Online (Sandbox Code Playgroud)

然后将文本复制到它并设置一些起始字体大小.然后你可以迭代你的while循环并在div的宽度合适时停止.然后将计算的字体大小设置为原始标题.

这样,这种检查将隐藏在用户的眼睛之外,因此它也将更快地工作.

顺便说一句:这是自动增长textarea脚本工作的常用方式.他们使用与原始文本区域具有相同样式设置的虚拟div,并在用户键入文本时调整区域的高度.因此,文本区域最初可能非常小,但如果用户输入大量文本,它将自动增长以容纳内容.

循环优化

您可以通过执行以下操作优化while循环以显着减少迭代次数:

  1. 设置起始字体大小.
  2. 得到测试DIV的宽度.
  3. 计算orig_div和test_div之间的宽度系数.
  4. 通过此因子调整字体大小,而不是增加/减少一个单位
  5. 测试test_div宽度

  • 如果有人做了这个工作的小提琴,我会给你业力; p (4认同)
  • @Tim:在关于while循环优化的答案中查看我的其他信息.它应该加快一点. (2认同)

小智 23

我有一个类似的问题,这让我为此编写了自己的插件.看看jquery-quickfit(这与Robert Koritnik的解决方案非常相似,我非常喜欢).

为了防止标题跨越多行,只需添加一个css样式:

white-space:nowrap;
Run Code Online (Sandbox Code Playgroud)

对元素.

在标题中包含jquery和quickfit之后.您可以使用以下命令触发快速配

$('h1').quickfit();
Run Code Online (Sandbox Code Playgroud)

它测量并计算文本的每个字母的大小不变量,以适合并使用它来计算适合文本到容器中的下一个最佳字体大小.

计算被缓存,这使得它在处理必须适合多个文本或必须多次适合文本时非常快,例如,在窗口调整大小时(调整大小几乎没有性能损失).

演示与您类似的情况

项目页面上有更多文档,示例和源代码.

  • 如果您删除换行符,所有JavaScript都是一行的! (10认同)
  • 该库是一个 oneliner :P (fittextjs) (2认同)

小智 20

以下是我经常使用的3个函数来获取文本宽度,高度并将大小调整为容器的宽度.

  • getTextWidth()将返回启动器中包含的文本的实际宽度.
  • getTextHeight(width)将返回包含在启动器中的包装文本的实际高度,具有指定的指定宽度.
  • 考虑到最小和最大尺寸,autoTextSize(minSize,maxSize,truncate)将调整容器内的文本大小以使其适合.
  • autoTruncateText()只显示用户可以实际看到的字符,并以"..."结束文本.
(function ($) {
  $.fn.getTextWidth = function() {
    var spanText = $("BODY #spanCalculateTextWidth");

    if (spanText.size() <= 0) {
      spanText = $("<span id='spanCalculateTextWidth' style='filter: alpha(0);'></span>");
      spanText.appendTo("BODY");
    }

    var valu = this.val();
    if (!valu) valu = this.text();

    spanText.text(valu);

    spanText.css({
      "fontSize": this.css('fontSize'),
      "fontWeight": this.css('fontWeight'),
      "fontFamily": this.css('fontFamily'),
      "position": "absolute",
      "top": 0,
      "opacity": 0,
      "left": -2000
    });

    return spanText.outerWidth() + parseInt(this.css('paddingLeft')) + 'px';
  };

  $.fn.getTextHeight = function(width) {
    var spanText = $("BODY #spanCalculateTextHeight");

    if (spanText.size() <= 0) {
      spanText = $("<span id='spanCalculateTextHeight'></span>");
      spanText.appendTo("BODY");
    }

    var valu = this.val();
    if (!valu) valu = this.text();

    spanText.text(valu);

    spanText.css({
      "fontSize": this.css('fontSize'),
      "fontWeight": this.css('fontWeight'),
      "fontFamily": this.css('fontFamily'),
      "top": 0,
      "left": -1 * parseInt(width) + 'px',
      "position": 'absolute',
      "display": "inline-block",
      "width": width
    });

    return spanText.innerHeight() + 'px';
  };

  /**
   * Adjust the font-size of the text so it fits the container.
   *
   * @param minSize     Minimum font size?
   * @param maxSize     Maximum font size?
   * @param truncate    Truncate text after sizing to make sure it fits?
   */
  $.fn.autoTextSize = function(minSize, maxSize, truncate) {
    var _self = this,
        _width = _self.innerWidth(),
        _textWidth = parseInt(_self.getTextWidth()),
        _fontSize = parseInt(_self.css('font-size'));

    while (_width < _textWidth || (maxSize && _fontSize > parseInt(maxSize))) {
      if (minSize && _fontSize <= parseInt(minSize)) break;

      _fontSize--;
      _self.css('font-size', _fontSize + 'px');

      _textWidth = parseInt(_self.getTextWidth());
    }

    if (truncate) _self.autoTruncateText();
  };

  /**
   * Function that truncates the text inside a container according to the
   * width and height of that container. In other words, makes it fit by chopping
   * off characters and adding '...'.
   */
  $.fn.autoTruncateText = function() {
    var _self = this,
        _width = _self.outerWidth(),
        _textHeight = parseInt(_self.getTextHeight(_width)),
        _text = _self.text();

    // As long as the height of the text is higher than that
    // of the container, we'll keep removing a character.
    while (_textHeight > _self.outerHeight()) {
      _text = _text.slice(0,-1);
      _self.text(_text);
      _textHeight = parseInt(_self.getTextHeight(_width));
      _truncated = true;
    }

    // When we actually truncated the text, we'll remove the last
    // 3 characters and replace it with '...'.
    if (!_truncated) return;
    _text = _text.slice(0, -3);

    // Make sure there is no dot or space right in front of '...'.
    var lastChar = _text[_text.length - 1];
    if (lastChar == ' ' || lastChar == '.') _text = _text.slice(0, -1);
    _self.text(_text + '...');
  };
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

  • autotruncate可以通过添加两个规则来实现纯CSS:'overflow:hidden'和'text-overflow:ellipsis'.我知道这真的很老了,但是嘿 - 也许有人会受益:) (10认同)

MeV*_*MeV 5

很简单。为文本创建一个跨度,获取宽度并减小字体大小,直到跨度与 div 容器的宽度相同:

while($("#container").find("span").width() > $("#container").width()) {
    var currentFontSize = parseInt($("#container").find("span").css("font-size")); 
    $("#container").find("span").css("font-size",currentFontSize-1); 
}
Run Code Online (Sandbox Code Playgroud)