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