it-swarm.com.de

Dynamischer Text in automatischer Größe, um einen Container mit fester Größe zu füllen

Ich muss den vom Benutzer eingegebenen Text in einer festen Größe div anzeigen lassen. Ich möchte, dass die Schriftgröße automatisch so angepasst wird, dass der Text die Box so weit wie möglich ausfüllt.

Also - wenn das div 400px x 300px ist. Wenn jemand ABC betritt, ist es eine wirklich große Schrift. Wenn sie einen Absatz eingeben, wäre dies eine kleine Schrift.

Ich möchte wahrscheinlich mit einer maximalen Schriftgröße beginnen - vielleicht 32px. Wenn der Text zu groß ist, um in den Container zu passen, verringern Sie die Schriftgröße, bis er passt.

297
GeekyMonkey

Danke Angriff . Ich wollte jQuery verwenden. 

Du hast mich in die richtige Richtung gerichtet, und das ist es, was mir endete:

Hier ist ein Link zum Plugin: https://plugins.jquery.com/textfill/
Und ein Link zur Quelle: http://jquery-textfill.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 });
});

und mein HTML ist so

<div class='jtextfill' style='width:100px;height:50px;'>
    <span>My Text Here</span>
</div>

Dies ist mein erstes Jquery-Plugin, daher ist es wahrscheinlich nicht so gut, wie es sein sollte. Hinweise sind auf jeden Fall willkommen.

159
GeekyMonkey

Ich fand keine der vorherigen Lösungen aufgrund von schlechter Leistung als ausreichend genug. Daher habe ich meine eigene gemacht, die einfache Mathematik statt Schleifen verwendet. Sollte auch in allen Browsern funktionieren.

Laut diesem Performance-Testfall ist es viel schneller als die anderen hier gefundenen Lösungen.

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

Wenn Sie beitragen möchten, habe ich this zu Gist hinzugefügt.

52
mekwall

So sehr ich die gelegentlichen Upvotes, die ich für diese Antwort bekomme, danke (danke!), Ist dies wirklich nicht die beste Lösung für dieses Problem. Bitte lesen Sie einige der anderen wundervollen Antworten, insbesondere diejenigen, die Lösungen gefunden haben, ohne zu schleifen.


Zur Information hier noch meine ursprüngliche Antwort :

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

Und hier ist eine Version mit Klassen :

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

Die meisten anderen Antworten verwenden eine Schleife, um die Schriftgröße zu reduzieren, bis sie in das div-Format passt. Dies ist sehr langsam, da die Seite das Element jedes Mal erneut rendern muss, wenn sich die Schriftgröße ändert. Ich musste schließlich meinen eigenen Algorithmus schreiben, damit er so funktioniert, dass ich den Inhalt regelmäßig aktualisieren kann, ohne den Browser des Benutzers einzufrieren. Ich habe einige weitere Funktionen hinzugefügt (Text drehen, Padding hinzufügen) und als jQuery-Plugin verpackt.

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

einfach anrufen

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

und es passt gut zu Ihrem Behälter.

Sehen Sie es hier in Aktion:

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

Im Moment gibt es einige Einschränkungen, das div muss eine feste Höhe und Breite haben und es wird kein Text in mehrere Zeilen umbrochen.

Ich werde daran arbeiten, eine Option zur Einstellung der maximalen Schriftgröße zu erhalten.

Edit: Ich habe einige Probleme mit dem Plugin gefunden, es behandelt kein anderes Box-Modell als das Standardmodell und das div kann keine Ränder oder Ränder haben. Ich werde daran arbeiten.

Edit2: Ich habe jetzt diese Probleme und Einschränkungen behoben und weitere Optionen hinzugefügt. Sie können die maximale Schriftgröße festlegen. Sie können auch festlegen, ob die Schriftgröße entweder Breite, Höhe oder beides sein soll. Ich werde daran arbeiten, die Werte für max-width und max-height im Wrapper-Element zu akzeptieren.

Edit3: Ich habe das Plugin auf Version 1.2.0 aktualisiert. Bereinigung des Codes und neuer Optionen (verticalAlign, horizontalAlign, textAlign) und Unterstützung innerer Elemente im span-Tag (z. B. Zeilenumbrüche oder font-awesome-Symbole).

31
Hoffmann

Dies basiert auf dem, was GeekyMonkey mit einigen Änderungen oben veröffentlicht hat.

; (function($) {
/**
* Resize inner element to fit the outer element
* @author Some modifications by Sandstrom
* @author Code based on earlier works by Russ Painter ([email protected])
* @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);
9
sandstrom

Hier ist eine verbesserte Schleifenmethode, bei der die binäre Suche verwendet wird, um die größtmögliche Größe zu ermitteln, die in den übergeordneten Schritten in das übergeordnete Element passt. Der Code ist auch in mehrfacher Hinsicht für die Leistung optimiert.

Standardmäßig werden 10 binäre Suchschritte ausgeführt, die innerhalb von 0,1% der optimalen Größe liegen. Sie können stattdessen die Zahl auf einen bestimmten Wert N einstellen, um die optimale Größe innerhalb von 1/2 ^ N zu erreichen.

Rufen Sie es mit einem CSS-Selektor auf, zum Beispiel: fitToParent('.title-span');

/**
 * 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);
        }
    });
};
6
Luke Hutchison

Ich habe eine Direktive für AngularJS erstellt - stark von der Antwort von GeekyMonkey inspiriert, jedoch ohne die Abhängigkeit von jQuery.

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

Markup

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

Richtlinie

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();
      });
    }
  };
});
6
sqren

Ich habe das obige Skript von Marcus Ekwall herausgearbeitet: https://Gist.github.com/3945316 und es an meine Vorlieben angepasst. Es wird jetzt ausgelöst, wenn die Größe des Fensters geändert wird, sodass das Kind immer in seinen Container passt. Ich habe das Skript unten als Referenz eingefügt.

(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);
5
nimrod

Hier ist meine Modifikation der Antwort des OPs.

Kurzum, viele Leute, die versuchten, dies zu optimieren, beklagten sich über die Verwendung einer Schleife. Ja, während Schleifen langsam sein können, können andere Ansätze ungenau sein.

Daher verwendet mein Ansatz Binary Search, um die beste Schriftgröße zu finden:

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

Dadurch kann das Element auch die minimale und maximale Schriftart festlegen:

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

Darüber hinaus ist dieser Algorithmus ohne Einheit. Sie können em, rem, % usw. angeben und wird dies für das Endergebnis verwenden.

Hier ist die Geige: https://jsfiddle.net/fkhqhnqe/1/

4
Boom

Ich hatte genau das gleiche Problem mit meiner Website. Ich habe eine Seite, die auf einem Projektor, auf Wänden, großen Bildschirmen angezeigt wird.

Da ich die maximale Größe meiner Schrift nicht kenne, habe ich das Plugin von @GeekMonkey erneut verwendet, aber die Schriftgröße erhöht:

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

Die vorgeschlagenen iterativen Lösungen können an zwei Fronten dramatisch beschleunigt werden:

1) Multiplizieren Sie die Schriftgröße mit einer Konstanten, anstatt 1 hinzuzufügen oder zu entfernen.

2) Erstens, wenn Sie eine Kurskonstante verwenden, beispielsweise die doppelte Größe für jede Schleife. Dann mit einer groben Idee, wo Sie anfangen sollen, machen Sie dasselbe mit einer feineren Einstellung, zum Beispiel mit 1,1 multiplizieren. Der Perfektionist möchte zwar die genaue ganzzahlige Pixelgröße der idealen Schriftart, die meisten Beobachter bemerken den Unterschied zwischen 100 und 110 Pixeln jedoch nicht. Wenn Sie ein Perfektionist sind, wiederholen Sie ein drittes Mal mit einer noch feineren Einstellung.

Anstatt eine bestimmte Routine oder ein Plug-In zu schreiben, die die genaue Frage beantworten, verlasse ich mich einfach auf die Grundgedanken und schreibe Variationen des Codes, um alle Arten von Layoutproblemen zu behandeln, nicht nur Text, einschließlich passender Divs, Spannweiten, Bilder. .. nach Breite, Höhe, Fläche, ... innerhalb eines Containers, passend zu einem anderen Element ....

Hier ist ein Beispiel:

  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');
1
DaveWalley

Sie können FitText.js ( github page ) verwenden, um dieses Problem zu lösen. Ist im Vergleich zu TextFill wirklich klein und effizient. TextFill verwendet eine aufwendige while-Schleife und FitText nicht. 

Auch FitText ist flexibler (ich verwende es in einem Projekt mit sehr speziellen Anforderungen und funktioniert wie ein Champion!).

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>

Sie können auch Optionen dazu einstellen:

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

CSS:

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

Und wenn Sie es brauchen, hat FitText auch eine no-jQuery-Version .

1
eduludi

Hier ist eine Version der akzeptierten Antwort, die auch einen minFontSize-Parameter annehmen kann.

(function($) {
    /**
    * Resizes an inner element's font so that the inner element completely fills the outer element.
    * @author Russ Painter [email protected]
    * @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);
1
blak3r

BEARBEITEN: Dieser Code wurde verwendet, um Notizen zu einem HTML5-Video anzuzeigen. Sie ändert die Schriftgröße schnell, wenn die Größe des Videos geändert wird (wenn die Größe des Browser-Fensters geändert wird.) Die Notizen wurden mit dem Video verbunden (genau wie bei YouTube). Daher verwendet der Code Instanzen anstelle eines DOM-Handles direkt.

Auf Anfrage füge ich Code ein, den ich dazu verwendet habe. (Textfelder über einem HTML5-Video.) Der Code wurde vor langer Zeit geschrieben, und ich denke ehrlich gesagt, er ist ziemlich chaotisch. Da die Frage bereits beantwortet ist und eine Antwort bereits vor langer Zeit akzeptiert wurde, mache ich mir nichts daraus. Wenn jemand dies etwas vereinfachen möchte, sind Sie mehr als willkommen!

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

Sie müssen diese Zahlen wahrscheinlich von der Schriftfamilie zur Schriftfamilie anpassen. Ein guter Weg, dies zu tun, ist das Herunterladen eines kostenlosen Grafikvisualisierers namens GeoGebra. Ändern Sie die Länge des Textes und die Größe der Box. Dann legen Sie die Größe manuell fest. Tragen Sie die manuellen Ergebnisse in das Koordinatensystem ein. Dann geben Sie die zwei Gleichungen ein, die ich hier gepostet habe, und optimieren Sie die Zahlen, bis "mein" Graph auf Ihre manuell eingezeichneten Punkte passt.

1
Friend of Kim

ich weiß, dass dies ein Oldie ist, aber es gibt immer noch Leute, die diese Funktionalität benötigen. Ich habe mich für die geekMonkey-Lösung entschieden, aber es ist einfach klasse. einfach weil es langsam ist. Was er tut, ist, dass er die Schriftgröße auf Maximum stellt (maxFontPixels) und dann prüft, ob sie in den Container passt. Andernfalls wird die Schriftgröße um 1 Pixel reduziert und erneut geprüft. Warum nicht einfach den vorherigen Container auf die Höhe prüfen und diesen Wert übergeben? (Ja, ich weiß warum, aber ich habe jetzt eine Lösung gemacht, die nur auf der Höhe funktioniert und auch eine Min/Max-Option hat.)

viel schnellere Lösung:

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

und das wäre das HTML:

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

nochmals: Diese Lösung prüft NUR die Höhe des Containers. Deshalb muss diese Funktion nicht prüfen, ob das Element hineinpasst. Ich habe aber auch einen Min/Max-Wert (40min, 150max) implementiert. Für mich funktioniert das einwandfrei (und funktioniert auch bei der Fenstergröße).

0
honk31

Ich habe einen Weg gefunden, um die Verwendung von Schleifen zu verhindern, um den Text zu verkleinern. Es passt die Schriftgröße an, indem es für die Rate zwischen Containerbreite und Inhaltsbreite multipliziert wird. Wenn also die Breite des Containers 1/3 des Inhalts beträgt, wird die Schriftgröße um 1/3 und die Breite des Containers reduziert. Zum Vergrößern habe ich eine while-Schleife verwendet, bis der Inhalt größer als der Container ist.

function fitText(outputSelector){
    // max font size in pixels
    const maxFontSize = 50;
    // get the DOM output element by its selector
    let outputDiv = document.getElementById(outputSelector);
    // get element's width
    let width = outputDiv.clientWidth;
    // get content's width
    let contentWidth = outputDiv.scrollWidth;
    // get fontSize
    let fontSize = parseInt(window.getComputedStyle(outputDiv, null).getPropertyValue('font-size'),10);
    // if content's width is bigger than elements width - overflow
    if (contentWidth > width){
        fontSize = Math.ceil(fontSize * width/contentWidth,10);
        fontSize =  fontSize > maxFontSize  ? fontSize = maxFontSize  : fontSize - 1;
        outputDiv.style.fontSize = fontSize+'px';   
    }else{
        // content is smaller than width... let's resize in 1 px until it fits 
        while (contentWidth === width && fontSize < maxFontSize){
            fontSize = Math.ceil(fontSize) + 1;
            fontSize = fontSize > maxFontSize  ? fontSize = maxFontSize  : fontSize;
            outputDiv.style.fontSize = fontSize+'px';   
            // update widths
            width = outputDiv.clientWidth;
            contentWidth = outputDiv.scrollWidth;
            if (contentWidth > width){
                outputDiv.style.fontSize = fontSize-1+'px'; 
            }
        }
    }
}

Dieser Code ist Teil eines Tests, den ich in Github hochgeladen habe https://github.com/ricardobrg/fitText/

0
Ricardo BRGWeb

Ich wollte nur meine Version für contenteditables hinzufügen.

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

0
wutzebaer

Ich habe das gleiche Problem und die Lösung ist im Grunde Javascript zur Steuerung der Schriftgröße. Überprüfen Sie dieses Beispiel auf codepen: 

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

Dieses Beispiel bezieht sich nur auf die Höhe. Möglicherweise müssen Sie einige Angaben machen, wenn es sich um die Breite handelt.

versuchen Sie, die Größe zu ändern 

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

Ich habe gemocht

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));
0
Tuan Nguyen