【问题标题】:Fit text perfectly inside a div (height and width) without affecting the size of the div在不影响 div 大小的情况下,将文本完美地放入 div(高度和宽度)内
【发布时间】:2014-08-14 03:23:03
【问题描述】:

我提前道歉,因为我知道这个问题之前已经出现过很多次,但我似乎无法找到正确的解决方案(相信我,我已经尝试了一些!)

基本上它是旧的“在不影响 div 的大小的情况下完美地适应 div 内的文本”。除非我是个十足的笨蛋,否则我相信 CSS 无法做到这一点。所以我的意思基本上是而不是做类似的事情:

#someDiv {
font-size: 12px;
}

或者...

#someDiv {
font-size: 1em;
}

...我希望能够做这样的事情:

#someDiv {
font-size: fluid;
}

...意思是这个 div 包含的任何文本,缩放它以完全适合从左到右和从上到下,没有溢出或空白。

在浏览了无数网站寻找这种 CSS 解决方案之后,我现在已经接受 CSS 无法做到这一点......所以,输入 jQuery。

我在网上找到了几个 jQuery 解决方案,但它们只会缩放文本以适应宽度,但我希望它也能缩放到高度。如此有效地我想对 jQuery 说:

“jQuery,找到 $(this) div 和其中的任何文本,我希望你缩放它,使其尽可能紧密地填充 div 的整个高度和宽度”。

如果我没有很好地解释自己,我附上了一张图表,解释了我面临的问题和我正在寻找的解决方案。

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 在溢出的情况下,这是否意味着您需要滚动条,或者您需要调整文本大小以适应?
  • @YannickY 他显然是指调整文本大小以填充但不溢出内容 div。这是可行的,但我想不出一个好的方法。如果我有时间,我稍后会为你回答这个问题:)。
  • 不,滚动条是我试图避免的一部分。我基本上希望文本的大小与给定的 div 一样大或小。没有滚动条。没有溢出。没有空格。只是从上到下和从左到右的纯文本。谢谢。
  • 只是想确定一下,因为如果你有太多字符,我假设你会减小字体大小?那么字体大小会不会在某些时候太小?
  • 我只是在考虑极端情况下的逻辑,不是几个字就是太多字(在调整文本大小时)

标签: jquery css font-size


【解决方案1】:

这是相同的答案,但在 Javascript 中

var autoSizeText;

autoSizeText = function() {
  var el, elements, _i, _len, _results;
  elements = $('.resize');
  console.log(elements);
  if (elements.length < 0) {
    return;
  }
  _results = [];
  for (_i = 0, _len = elements.length; _i < _len; _i++) {
    el = elements[_i];
    _results.push((function(el) {
      var resizeText, _results1;
      resizeText = function() {
        var elNewFontSize;
        elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) - 1) + 'px';
        return $(el).css('font-size', elNewFontSize);
      };
      _results1 = [];
      while (el.scrollHeight > el.offsetHeight) {
        _results1.push(resizeText());
      }
       return _results1;
    })(el));
  }
  return _results;
};

$(document).ready(function() {
  return autoSizeText();
});

顺便说一句...如果您需要将 coffeescript 转换为 javascript,只需转到 js2coffee.org

【讨论】:

  • “这是相同的答案,但在 Javascript 中” :) 哇,所以我们不必下载 jQuery 库!伟大的!顺便说一句...... jQuery 中不需要“px”。
  • @RokoC.Buljan javasacript 是语言,jQuery 只是一个库(一个很棒的库)。从中复制的答案是咖啡脚本是一种不同的语言。
【解决方案2】:

我最近也想要类似的东西:

<div class='container'>
    <div class='no-resize'>This text won't be resized and will go out of the div.</div>
    <div class='resize'>This text will be resized and wont go out of the div.</div>
</div>

.no-resize, .resize {
    width: 100px;
    height: 50px;
    border: 1px solid #000;
    color: #000;
    float: left;
    margin-left: 10px;
    font-size: 15px
}

jsfiddle.net/mn4rr/1/ 的提琴手。

【讨论】:

  • 哇,看起来不错!真的很好!谢谢你。这可能是我正在寻找的解决方案。但不幸的是(无论如何对我来说)它是用 CoffeeScript 编写的,我对此一无所知。你会碰巧知道我是怎么用 jQuery 写这个的吗?再次感谢。
  • 我使用了 js2coffee.org,所以显然得到了与 joshboley 相同的结果,但是我无法让它在 jsfiddle 中以相同的方式运行。你也许可以。
  • 看起来这似乎做得足够好 --> http://jsfiddle.net/LrCFY/3/ 它可能并不完美,但它现在应该可以完成这项工作。谢谢大家!
  • 这个解决方案的问题是它需要你在CSS中提前手动设置最大字体大小,然后它会缩小以适应。 IMO 与所要求的不符:例如:增长/缩小以适应。我还认为使用像素进行大小调整意味着您很少会紧密匹配,使用 em 值会更好。
  • 优点@MrN00b — 我完全同意。但不幸的是,这是我发现的最接近的答案。
【解决方案3】:

我没有足够的声誉来评论接受的答案,所以我做了一个回答。如果height 上有一个css3 转换,那么上面的autoSizeText()$.resizeText 答案就有问题。我做了一个简短的 jquery 插件来解决这个问题。

$.fn.resizeText = function (options) {

    var settings = $.extend({ maxfont: 40, minfont: 4 }, options);

    var style = $('<style>').html('.nodelays ' +
    '{ ' +
        '-moz-transition: none !important; ' +
        '-webkit-transition: none !important;' +
        '-o-transition: none !important; ' +
        'transition: none !important;' +
    '}');

    function shrink(el, fontsize, minfontsize)
    {
        if (fontsize < minfontsize) return;

        el.style.fontSize = fontsize + 'px';

        if (el.scrollHeight > el.offsetHeight) shrink(el, fontsize - 1, minfontsize);
    }

    $('head').append(style);

    $(this).each(function(index, el)
    {
        var element = $(el);

        element.addClass('nodelays');

        shrink(el, settings.maxfont, settings.minfont);

        element.removeClass('nodelays');
    });

    style.remove();
}

要使用这个插件你只需要调用

 $(selector).resizeText();

我希望这可以节省其他人一些时间进行故障排除。我浪费了整整 20 分钟的时间来思考为什么上面的代码会导致我的页面出现无限循环。

【讨论】:

  • 谢谢凯尔特。接受的答案对我不起作用。看到文字大小没有变化。你做得很好...+1
  • 为完美作品添加一些风格:{overflow-y:scroll;宽度:100%;最大高度:20px;溢出换行:断字;}
【解决方案4】:

我通过制作一个 jQuery 插件解决了这个问题,它在这里:http://jsfiddle.net/c9YNz/2/(已更新以处理调整窗口大小)

插件的代码只是将文本缩小到 0.01em 大小,然后将其放大以适应,这是插件代码:

$.fn.resizeText = function () {
    var width = $(this).innerWidth();
    var height = $(this).innerHeight();
    var html =  $(this).html();
    var newElem = $("<div>", {
        html: html,
        style: "display: inline-block;overflow:hidden;font-size:0.1em;padding:0;margin:0;border:0;outline:0"
    });

    $(this).html(newElem);
    $.resizeText.increaseSize(10, 0.1, newElem, width, height);

    $(window).resize(function () {
        if ($.resizeText.interval)
            clearTimeout($.resizeText.interval)

        $.resizeText.interval = setTimeout(function () {
            elem.html(elem.find("div.createdResizeObject").first().html());
            elem.resizeText();
        }, 300);
    });
}

$.resizeText = {
    increaseSize: function (increment, start, newElem, width, height) {
        var fontSize = start;

        while (newElem.outerWidth() <= width && newElem.outerHeight() <= height) {
            fontSize += increment;
            newElem.css("font-size", fontSize + "em");
        }

        if (newElem.outerWidth() > width || newElem.outerHeight() > height) {
            fontSize -= increment;
            newElem.css("font-size", fontSize + "em");
            if (increment > 0.1) {
                $.resizeText.increaseSize(increment / 10, fontSize, newElem, width, height);
            }
        }
    }
};

如果你有这个html:

<div class="resizeText" style="width:1200px;height:400px;">
Insert text from slipsum here.
</div>

你这样称呼它:

$(document).ready(function () {
    $(".resizeText").resizeText();
});

这不是最好的方法,但我想这对你来说已经足够了(而且它有效)。

【讨论】:

  • 谢谢。但是,当我将容器的大小更改为百分比值(对于响应式设计对我来说很重要)时,它似乎破坏了它并且文本溢出了容器之外? --> http://jsfiddle.net/c9YNz/。在我看来,这种方式似乎更全面--> http://jsfiddle.net/LrCFY/3/
  • @BenClarke 它适用于我的百分比(包括您链接的小提琴),您使用的是哪个浏览器(我没有进行广泛的测试)?我刚刚在最新版本的 Chrome、IE 和 Firefox 中做了一个快速测试,它运行良好。很想知道为什么它不适合你。
  • 我使用的是最新的 Chrome。那很奇怪吗?这是截图 --> Screenshot
  • 您可能需要再次单击“运行”。我猜这是由窗口调整大小(或没有单击“运行”的 CSS 编辑)引起的。我将更新小提琴以调整窗口大小。
  • @BenClarke 给你:jsfiddle.net/c9YNz/2(我也更新了原来的答案。
【解决方案5】:

这是给定答案的略微修改版本。

要求

  1. 包含文本的类具有“resize”类。
  2. 它包含高度和宽度(%, px, 不管...)

这个版本有什么变化?

  1. 我添加了调整大小(通过将事件调整大小绑定到函数)autoSizeText。这远非理想,但如果我们不调整很多大小,应该没问题。
  2. 在以前的版本中,文本只会越来越小。现在它会尝试在不超出 div 的情况下找到最大的字体。

注意:

我并没有声称代码已经准备好生产。但是,如果您发现可以增强的东西,请与社区分享。

var autoSizeText = function () {
    var el, elements, _i, _len;
    elements = $('.resize');
    if (elements.length < 0) {
        return;
    }
    for (_i = 0, _len = elements.length; _i < _len; _i++) {
        el = elements[_i];
        dichoFit = function (el) {

            diminishText = function () {
                var elNewFontSize;
                elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) - 1) + 'px';

                return $(el).css('font-size', elNewFontSize);
            };
            augmentText = function () {
                var elNewFontSize;
                elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) + 1) + 'px';

                return $(el).css('font-size', elNewFontSize);
            };


            diminishText();
            while (el.scrollHeight < el.offsetHeight) {
                augmentText();
            }
            augmentText();
            while (el.scrollHeight > el.offsetHeight) {
                diminishText();
            }

        }
        dichoFit(el);
    }
};

$(document).ready(function () {
    autoSizeText();
    $(window).resize(function resizeText(){
        autoSizeText()
    })
});
.sizable{
 width: 50vw;
 height: 50vh;
 border: 2px solid darkred;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  <div class='sizable resize'>
  I am a sizable div and I have explicit width and height.
</div>

【讨论】:

  • 这是一个了不起的答案,似乎比这里的其他答案有了很大的改进。但是,如果我从最大化状态恢复窗口,脚本似乎会失败。我必须开始调整窗口大小以激活脚本。你知道是否有一种方法可以修改它来实现这一点?
【解决方案6】:

抱歉回答晚了,但可以节省很多时间, 我编写的这段代码在调整窗口大小时完美运行。

function fitTextInDiv(){
    if($this.find('.text-wrapper').height() > $this.find('.aligned-text').height() ){
        while( $this.find('.text-wrapper').height() > $this.find('.aligned-text').height() ) {
             $this.find('.aligned-text').css('font-size', (parseFloat($this.find('.aligned-text').css('font-size')) + 0.1) + "px" );
        }
    }
    else if($this.find('.text-wrapper').height() < $this.find('.aligned-text').height() ){
        while( $this.find('.text-wrapper').height() < $this.find('.aligned-text').height() ) {
            $this.find('.aligned-text').css('font-size', (parseFloat($this.find('.aligned-text').css('font-size')) - 0.1) + "px" );
        }

     }
}

其中 text-wrapper 是父级,aligned-text 是子级 div。您必须指定父元素的高度和宽度。在调整大小时,您可以使用 jquery 设置父元素的高度和宽度,然后调用此函数。

我写这段代码是因为我尝试了很多插件,但它们不支持调整窗口大小。

【讨论】:

    【解决方案7】:

    我遇到了同样的问题,解决方案基本上是使用 javascript 来控制字体大小。 在 codepen 上查看此示例:

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

    尝试调整它的大小

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

    【讨论】:

      【解决方案8】:

      这是我的版本。这是在 React 项目上使用 ES6 构建的。

      export function autoSizeText(container, attempts=30) {
        let setChildrenToInheritFontSize = ( el ) => {
          el.style.fontSize = 'inherit';
          _.each( el.children, (child) => {
            setChildrenToInheritFontSize( child );
          });
        };
      
      
        let resizeText = (el) => {
          attempts--;
          let elNewFontSize;
          if( el.style.fontSize === "" ||  el.style.fontSize === "inherit" ||  el.style.fontSize === "NaN" ){
            elNewFontSize = '32px'; // largest font to start with
          } else {
            elNewFontSize = (parseInt(el.style.fontSize.slice(0, -2)) - 1) + 'px';
          }
          el.style.fontSize = elNewFontSize;
      
          // this function can crash the app, so we need to limit it
          if( attempts <= 0 ) {
            return;
          }
      
          if ( (el.scrollWidth > el.offsetWidth) || (el.scrollHeight > el.offsetHeight)) {
            resizeText(el);
          }
        };
        setChildrenToInheritFontSize( container );
        resizeText(container);
      }
      

      【讨论】:

        【解决方案9】:

        我最近有一个最大宽度的 div,它从文本输入字段接收文本,我必须使文本适合该 div,所以这是我解决它的方法(简单 JS,无插件):

        function addName(){
            let maxWidth = 550;
            let defaultFontSize = 50;
            let entry = document.getElementById('nameInput').value;
            let nameDiv = document.getElementById('name');
            let fontSize = nameDiv.style["font-size"];
            fontSize = fontSize.replace('px','');
            fontSize = parseInt(fontSize);
            nameDiv.innerText = entry;
            if (nameDiv.clientWidth > maxWidth) {
                fontSize = fontSize - 2.5;
                nameDiv.style["font-size"] = `${fontSize}px`;
            } else if (nameDiv.clientWidth < maxWidth && fontSize < defaultFontSize ) {
                fontSize = fontSize + 2.5;
                nameDiv.style["font-size"] = `${fontSize}px`;
            }
        }
        #name {
            height: 70px;
            line-height: 70px;
            text-align: center;
            overflow: hidden;
            width: auto;
            display: table; /*THAT DOES THE MAGIC*/
            margin: auto;
            border: 1px solid black
        /* THE BORDER IS FOR TEST PURPOSES TO SEE WHAT'S HAPPENING WITH THE DIV*/
        }
        <input type="text" id="nameInput" oninput="addName()">
        <div id="name" style="font-size: 50px;"></div>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多