Fit text perfectly inside a div (height and width)

2019-01-11 01:35发布

I apologise in advance as I know this question has come up many times before but I just can't seem to find the right solution (and believe me I've tried a few!)

Basically it's the old "Fit text perfectly inside a div without affecting the size of the div". And unless I'm a complete numpty, I believe CSS has no way of doing this. So what I mean basically is rather than doing something like:

#someDiv {
font-size: 12px;
}

or...

#someDiv {
font-size: 1em;
}

...I want to be able to do something like this:

#someDiv {
font-size: fluid;
}

...meaning that whatever text this div contains, scale it to fit perfectly from left to right and top to bottom with no overflow or whitespace.

After trawling through countless websites looking for this CSS solution, I've now accepted that CSS isn't capable of this ...so, enter jQuery.

I've found several jQuery solutions online but they will only scale the text to fit the width, but I want it to scale to the height as well. So effectively I want to say to jQuery:

"jQuery, find $(this) div and whatever text is inside it I want you to scale it so that it fills the entire height and width of the div as tightly as possible".

In case I haven't explained myself very well, I've attached a graphic explaining the problem I'm facing and the solution I'm looking for.

Any help would be much appreciated. Thank you.

enter image description here

8条回答
地球回转人心会变
2楼-- · 2019-01-11 02:02

I don't have enough reputation to comment on the accepted answer so I made an answer. If height has a css3 transition on it the autoSizeText() and $.resizeText answers above have issues. I made a short jquery plugin to fix this.

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

To use this plugin you only need to call

 $(selector).resizeText();

I hope this saves someone else some time troubleshooting. I wasted a good 20 minutes scratching my head wondering why the code above was causing an infinite loop on my page.

查看更多
女痞
3楼-- · 2019-01-11 02:05

Here's my version. This is build with ES6 on a React project.

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);
}
查看更多
登录 后发表回答