it-swarm.com.de

Fontskalierung basierend auf der Breite des Containers

Es fällt mir schwer, mich mit der Schriftskalierung zu beschäftigen.

Ich habe derzeit diese Seite mit einem font-size von 100%. 100% von was aber? Dies scheint sich bei 16px auszurechnen. 

Ich hatte den Eindruck, dass sich 100% irgendwie auf die Größe des Browserfensters beziehen, aber anscheinend nicht, weil es immer 16px ist, ob die Größe des Fensters auf eine mobile Breite oder einen ausgewachsenen Widescreen-Desktop reduziert wird.

Wie kann ich den Text meiner Site in Bezug auf den Container skalieren? Ich habe versucht, em zu verwenden, aber das skaliert auch nicht.

Meine Begründung ist, dass Dinge wie mein Menü bei der Größenänderung zermalmt werden. Daher muss ich den px font-size von .menuItem unter anderen Elementen in Bezug auf die Breite des Containers reduzieren. (Zum Beispiel funktioniert das Menü auf einem großen Desktop perfekt, 22px funktioniert einwandfrei. Gehen Sie zur Tablettbreite, und 16px ist angemessener.)

Es ist mir bewusst, dass ich Haltepunkte hinzufügen kann, aber ich möchte, dass der Text mit zusätzlichen Haltepunkten skaliert wird. Andernfalls bekomme ich hunderte von Haltepunkten für jede 100px-Abnahme, um den Text zu kontrollieren.

917
Francesca

EDIT: Wenn der Container nicht der Body ist CSS Tricks deckt alle Ihre Optionen hier ab: https://css-tricks.com/fitting-text-to-a-container/

Wenn es sich bei dem Container um den Körper handelt, suchen Sie nach Viewport-Prozentlängen :

Die viewport-percent-Längen sind relativ zur Größe des initialen enthaltenden Blocks . Wenn die Höhe oder Breite des anfänglichen enthaltenden Blocks geändert wird, werden sie entsprechend skaliert. Wenn der Überlaufwert des Stammelements jedoch "auto" ist, wird davon ausgegangen, dass keine Bildlaufleisten vorhanden sind. 

Die Werte sind: 

  • vw (% der Breite des Ansichtsfensters)
  • vh (% der Höhe des Ansichtsfensters)
  • vi (1% der Größe des Darstellungsbereichs in Richtung der Inline-Achse des Wurzelelements)
  • vb (1% der Größe des Ansichtsfensters in Richtung der Blockachse des Stammelements)
  • vmin (die kleinere von vw oder vh)
  • vmax (die größere oder vw oder vh)

1 v * entspricht 1% des anfänglichen enthaltenden Blocks.

es sieht so aus:

p {
    font-size: 4vw;
}

Wie Sie sehen, wird die Schriftgröße auch mit zunehmender Breite des Ansichtsfensters größer, ohne dass Medienabfragen verwendet werden müssen.

Diese Werte sind eine Größeneinheit, genau wie px oder em. Sie können also auch zur Größenbestimmung anderer Elemente verwendet werden, z. B. Breite, Rand oder Auffüllung.

Die Browser-Unterstützung ist ziemlich gut, aber Sie werden wahrscheinlich einen Fallback benötigen, wie zum Beispiel:

p {
    font-size: 16px; 
    font-size: 4vw;
}

Schauen Sie sich die Support-Statistiken an: http://caniuse.com/#feat=viewport-units

Schauen Sie sich auch die CSS-Tricks an, um einen umfassenderen Look zu erhalten: http://css-tricks.com/viewport-sized-typography/

Hier ist ein schöner Artikel zum Einstellen der Min/Max-Größen und zur Kontrolle der Größen: http://madebymike.com.au/writing/precise-control-responsive-typography/

Und hier ist ein Artikel über das Einstellen Ihrer Größe mit calc (), damit der Text den Darstellungsbereich ausfüllt: http://codepen.io/CrocoDillon/pen/fBJxu

Bitte lesen Sie auch diesen Artikel, der eine Technik namens "geschmolzenes Leading" verwendet, um auch die Zeilenhöhe anzupassen. https://css-tricks.com/molten-leading-css/

1278
jbenjohnson

Aber was ist, wenn der Container nicht das Ansichtsfenster (der Körper) ist?

Diese Frage wird von Alex im Kommentar unter der akzeptierten Antwort gestellt.

Diese Tatsache bedeutet nicht, dass vw in gewissem Maße nicht für die Größe dieses Containers verwendet werden kann. Um nun eine Variation überhaupt zu sehen, muss man annehmen, dass der Behälter in irgendeiner Weise flexibel in der Größe ist. Ob durch einen direkten Prozentsatz width oder durch 100% minus Margen. Der Punkt wird "moot", wenn der Container immer auf 200px wide gesetzt ist - dann setzen Sie einfach einen font-size, der für diese Breite funktioniert.

Beispiel 1

Bei einem Container mit flexibler Breite muss jedoch berücksichtigt werden, dass der Container in gewisser Weise immer noch eine Größe außerhalb des Ansichtsfensters hat . Daher muss die Einstellung vw basierend auf dem prozentualen Größenunterschied zum Ansichtsfenster angepasst werden, was bedeutet, dass die Größe der übergeordneten Wrapper berücksichtigt wird. Nehmen Sie dieses Beispiel :

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       So if the container is 50% of viewport (as here)
       then factor that into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
    */
    font-size: 2.5vw; 
}

Angenommen, div ist ein untergeordnetes Element von body, dann ist es 50% von dieser 100% Breite, die in diesem Grundfall die Ansichtsfenstergröße ist. Grundsätzlich möchten Sie ein vw festlegen, das für Sie gut aussieht. Wie Sie in meinem Kommentar im obigen CSS sehen können, können Sie dies mathematisch in Bezug auf die Größe des gesamten Ansichtsfensters "durchdenken", aber Sie brauchen nicht , um dies zu tun. Der Text wird mit dem Container "gebogen", da der Container mit der Größenänderung des Ansichtsfensters gebogen wird. UPDATE: hier ein Beispiel für zwei unterschiedlich große Container .

Beispiel 2

Sie können die Größe des Ansichtsfensters sicherstellen, indem Sie die Berechnung darauf basierend erzwingen. Betrachten Sie dieses Beispiel :

html {width: 100%;} /* force html to be viewport width */
body {width: 150%; } /* overflow the body */

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       Here, the body is 150% of viewport, but the container is 50% 
       of viewport, so both parents factor  into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 3.75vw 
       (5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
    */
    font-size: 3.75vw; 
}

Die Größe basiert immer noch auf dem Ansichtsfenster, wird jedoch im Wesentlichen basierend auf der Containergröße selbst festgelegt.

Sollte sich die Größe des Containers dynamisch ändern ...

Wenn die Größe des Containerelements entweder über @media Haltepunkte oder über Javascript dynamisch seine prozentuale Beziehung ändern würde, müsste unabhängig vom Basisziel eine Neuberechnung durchgeführt werden, um dieselbe "Beziehung" für die Textgröße beizubehalten.

Nimm Beispiel 1 oben. Wenn div entweder durch 25% oder durch Javascript auf @media umgeschaltet wurde, muss font-size gleichzeitig entweder in der Medienabfrage oder durch Javascript angepasst werden zur neuen Berechnung von 5vw * .25 = 1.25. Dies würde die Textgröße auf die gleiche Größe bringen, wie sie gewesen wäre, wenn die "Breite" des ursprünglichen Containers 50% gegenüber der Größe des Ansichtsfensters um die Hälfte reduziert worden wäre, dies wurde jedoch jetzt aufgrund einer Änderung der eigenen prozentualen Berechnung reduziert .

Eine Herausforderung

Wenn die CSS3-Funktion calc() verwendet wird, ist eine dynamische Anpassung schwierig, da diese Funktion derzeit nicht für font-size -Zwecke funktioniert. Sie könnten also keine reine CSS3-Anpassung vornehmen, wenn sich Ihre Breite bei calc() ändert. Natürlich ist eine geringfügige Anpassung der Breite für Ränder möglicherweise nicht ausreichend, um eine Änderung von font-size zu rechtfertigen, sodass dies möglicherweise keine Rolle spielt.

297
ScottS

Was ich in einem meiner Projekte mache, ist eine "Mischung" zwischen vw und vh, um die Schriftgröße an meine Bedürfnisse anzupassen, zB:

font-size: calc(3vw + 3vh);

Ich weiß, dass dies die Frage des Opers nicht beantwortet, aber vielleicht kann es eine Lösung für alle anderen sein.

29
lsblsb

Lösung mit SVG:

<div style="width: 60px;">  
  <svg width="100%" height="100%" viewBox="0 -200 1000 300"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text font-size="300" fill="black">Text</text>
  </svg>
</div>

https://jsfiddle.net/qc8ht5eb/

27
Danto

Es gibt eine große Philosophie für diese Ausgabe. Am einfachsten wäre es, dem Körper eine bestimmte Schriftgröße zu geben (ich empfehle 10), und dann hätten alle anderen Elemente ihre Schrift in em oder rem . Ich gebe dir ein Beispiel Um diese Einheiten zu verstehen, ist Em immer relativ zu seinen Eltern

body{font-size:10px;}
.menu{font-size:2em;} /* that means 2*10px = 20px */
.menu li{font-size:1.5em;} /* that means 1.5*20px = 30px */

Rem ist immer relativ zum Körper

body{font-size:10px;}
.menu{font-size:2rem;} /* that means 2*10px = 20px */
.menu li{font-size:1.5rem;} /* that means 1.5*10px = 15px */

Und dann könnten Sie ein Skript erstellen, das die Schriftgröße relativ zu Ihrer Containerbreite ändert. Dies ist jedoch nicht das, was ich empfehlen würde. In einem Container mit einer Breite von 900px haben Sie beispielsweise ein p-Element mit einer Schriftgröße von 12px. Und auf Ihrer Idee würde das auf 300px Breite Container bei 4px Schriftgröße werden. Es muss eine Untergrenze geben. Eine andere Lösung wäre bei Medienabfragen, damit Sie die Schrift für unterschiedliche Breiten einstellen können.

Aber die Lösungen, die ich empfehlen würde, ist die Verwendung einer Javascript-Bibliothek, die Ihnen dabei hilft. Und fittext.js die ich bisher gefunden habe.

21

Aktualisiert, weil ich eine Abstimmung erhalten habe.

Hier ist die Funktion:

document.body.setScaledFont = function(f) {
  var s = this.offsetWidth, fs = s * f;
  this.style.fontSize = fs + '%';
  return this
};

Konvertieren Sie dann alle Schriftarten für untergeordnete Elemente Ihrer Dokumente in em oder%.

Fügen Sie dann so etwas zu Ihrem Code hinzu, um die Basisschriftgröße festzulegen.

document.body.setScaledFont(0.35);
window.onresize = function() {
    document.body.setScaledFont(0.35);
}

http://jsfiddle.net/0tpvccjt/

20
tnt-rox

Pure-CSS-Lösung mit calc(), CSS-Einheiten und Mathematik

Dies ist genau nicht das, was OP verlangt, aber es kann jemandem den Tag bescheren. Diese Antwort ist nicht einfach zu löffeln und erfordert einige Nachforschungen im Entwicklerbereich.

Ich kam schließlich, um eine reine CSS-Lösung dafür zu bekommen, indem calc() mit verschiedenen Einheiten verwendet wurde. Sie benötigen ein grundlegendes mathematisches Verständnis von Formeln, um Ihren Ausdruck für calc() zu erarbeiten.

Als ich das ausarbeitete, musste ich einen responsive Header mit ganzer Seitenbreite und ein paar Eltern in DOM auffüllen. Ich werde meine Werte hier verwenden und sie durch Ihre eigenen ersetzen.

Zur Mathematik

Du wirst brauchen:

  • schön eingestelltes Verhältnis in irgendeinem Ansichtsfenster, ich habe 320px verwendet, also habe ich 24px hoch und 224px breit, das Verhältnis ist also 9.333 ... oder 28/3
  • die Containerbreite hatte ich padding: 3em und volle Breite, so dass dies zu 100wv - 2 * 3em

X ist die Breite des Containers. Ersetzen Sie ihn also durch Ihren eigenen Ausdruck oder passen Sie den Wert an, um ganzseitigen Text zu erhalten. R ist das Verhältnis, das Sie haben werden. Sie können es erhalten, indem Sie die Werte in einem Ansichtsfenster anpassen, die Breite und Höhe des Elements prüfen und durch Ihre eigenen Werte ersetzen. Es ist auch width / heigth;) 

x = 100vw - 2 * 3em = 100vw - 6em
r = 224px/24px = 9.333... = 28 / 3

y = x / r
  = (100vw - 6em) / (28 / 3)
  = (100vw - 6em) * 3 / 28
  = (300vw - 18em) / 28
  = (75vw - 4.5rem) / 7

Und bang! Es funktionierte! Ich hab geschrieben 

font-size: calc((75vw - 4.5rem) / 7)

zu meinem Header und es hat sich in jedem Ansichtsfenster gut angepasst.

Aber wie funktioniert das?

Wir brauchen hier oben Konstanten. 100vw bedeutet die gesamte Breite des Ansichtsfensters. Mein Ziel war es, einen Header mit voller Breite und etwas Auffüllung zu erstellen.

Das Verhältnis. Durch das Erhalten einer Breite und Höhe in einem Ansichtsfenster erhielt ich ein Verhältnis, mit dem ich spielen konnte, und mit dem Verhältnis weiß ich, wie hoch die Höhe in einem anderen Ansichtsfenster sein sollte. Das Berechnen mit der Hand würde viel Zeit in Anspruch nehmen und zumindest viel Bandbreite erfordern, daher ist es keine gute Antwort.

Fazit

Ich frage mich, warum niemand das herausgefunden hat, und einige Leute sagen sogar, dass es unmöglich wäre, mit CSS zu basteln. Ich mag es nicht, Javascript zum Anpassen von Elementen zu verwenden, daher akzeptiere ich keine JS- oder gar jQuery-Antworten, ohne mehr zu suchen. Alles in allem ist es gut, dass dies herausgefunden wurde, und dies ist ein Schritt zu reinen CSS-Implementierungen im Website-Design. 

Ich entschuldige mich für ungewöhnliche Konventionen in meinem Text. Ich bin kein englischer Muttersprachler und auch ziemlich neu beim Schreiben von SO - Antworten.

Edit : Es sollte auch beachtet werden, dass wir in manchen Browsern böse Scrollbalken haben. Bei der Verwendung von Firefox ist mir zum Beispiel aufgefallen, dass 100vw die gesamte Breite des Ansichtsfensters bedeutet, das sich unter der Bildlaufleiste erstreckt (wo sich der Inhalt nicht erweitern kann!). Daher muss der Text mit voller Breite sorgfältig begrenzt werden und vorzugsweise mit vielen Browsern und Geräten getestet werden.

18
hegez

Es gibt eine Möglichkeit, dies OHNE Javascript zu tun!

Sie können eine Inline-SVG verwenden. Sie können css für ein svg verwenden, wenn es Inline ist. Sie müssen bedenken, dass Ihre svg bei Verwendung dieser Methode auf die Containergröße anspricht.

Versuchen Sie es mit folgender Lösung ...

HTML

<div>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.96 358.98" >
      <text>SAVE $500</text>

  </svg>

</div>

CSS

div {
  width: 50%; /* set your container width */
  height: 50%; /* Set your container height */

}

svg {
  width: 100%;
  height: auto;

}

text {
  transform: translate(40px, 202px);
  font-size: 62px;
  fill: #000;

}

beispiel: https://jsfiddle.net/k8L4xLLa/32/

Willst du etwas auffälligeres?

Mit SVGs können Sie auch coole Sachen mit Formen und Junk machen. Sehen Sie sich diesen großartigen Anwendungsfall für skalierbaren Text an ...

https://jsfiddle.net/k8L4xLLa/14/

14
Aaron Loften

Dies ist zwar nicht besonders praktisch, aber wenn Sie möchten, dass font eine direkte Funktion des übergeordneten Elements ist, ohne dass ein JS vorhanden ist, das/die Loops (Intervalle) abhört, um die Größe der div/page zu lesen, gibt es eine Möglichkeit, dies zu tun. Iframes. Alles, was sich im iframe befindet, berücksichtigt die Größe des iframes als die Größe des Viewports. Der Trick besteht also darin, einfach einen iframe zu erstellen, dessen Breite der maximalen Breite entspricht, die der Text sein soll, und deren Höhe der maximalen Höhe entspricht * dem Seitenverhältnis des jeweiligen Textes. 

Abgesehen von der Einschränkung, dass Viewport-Einheiten nicht neben Elterneinheiten für Text verwendet werden können (wie in%, verhalten sich% wie alle anderen), bieten Viewport-Einheiten ein sehr leistungsfähiges Werkzeug: Die Min/Max-Dimension erhalten zu können . Das kannst du nirgendwo anders machen - du kannst es nicht sagen ... mach die Höhe dieses Divs von der Breite des Elternteils * etwas. 

Der Trick besteht jedoch darin, vmin zu verwenden und die Größe des Iframes so festzulegen, dass [Bruch] * Gesamthöhe eine gute Schriftgröße ist, wenn die Höhe das Begrenzungsmaß ist, und [Bruch] * Gesamtbreite, wenn die Breite die Breite ist begrenzende Dimension. Deshalb muss die Höhe ein Produkt der Breite und des Seitenverhältnisses sein. 

für mein spezielles Beispiel hast du

.main iframe{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: calc(3.5 * 100%);
  background: rgba(0,0,0,0);
  border-style: none;
  transform: translate3d(-50%,-50%,0);
}

Der kleine Ärger bei dieser Methode ist, dass Sie das CSS des iframe manuell einstellen müssen. Wenn Sie die gesamte CSS-Datei anhängen, würde dies für viele Textbereiche viel Bandbreite beanspruchen. Ich füge also die Regel hinzu, die ich direkt aus meinem CSS möchte.

var rule = document.styleSheets[1].rules[4];
var iDoc = document.querySelector('iframe').contentDocument;
iDoc.styleSheets[0].insertRule(rule.cssText); 

Sie können eine kleine Funktion schreiben, die die CSS-Regel bzw. alle CSS-Regeln abruft, die sich auf den Textbereich auswirken würden.

Ich kann mir keinen anderen Weg vorstellen, ohne JS zu hören. Die eigentliche Lösung wäre, dass Browser eine Möglichkeit bieten, Text als Funktion des übergeordneten Containers zu skalieren UND auch die gleichen Funktionen des Typs vmin/vmax bereitzustellen.

JS-Geige: https://jsfiddle.net/0jr7rrgm/3/ (Klicken Sie einmal, um das rote Quadrat mit der Maus zu verriegeln, klicken Sie erneut zum Freigeben.)

Die meisten JS in der Geige sind nur meine benutzerdefinierte Klick-Ziehen-Funktion

13
Roman Rekhler

Mit vw, em & co. funktioniert sicher, aber imo braucht immer die Berührung eines Menschen zur Feinabstimmung.

Hier ist ein Skript, das ich gerade geschrieben habe, basierend auf @ tnt-rox ' answer , das versucht, die Berührung dieses Menschen zu automatisieren:

$('#controller').click(function(){
	$('h2').each(function(){
    var
      $el = $(this),
      max = $el.get(0),
      el = null
    ;
    max =
      max
    ? max.offsetWidth
    : 320
    ;
    $el.css({
      'font-size': '1em',
      'display': 'inline',
    });
    el = $el.get(0);

    el.get_float = function(){
      var
        fs = 0
      ;
      if (this.style && this.style.fontSize) {
        fs = parseFloat(this.style.fontSize.replace( /([\d\.]+)em/g, '$1' ));
      }
      return fs;
    };

    el.bigger = function(){
      this.style.fontSize = (this.get_float() +0.1) +'em';
    };


    while ( el.offsetWidth < max ) {
      el.bigger();
    }
    // finishing touch.
    $el.css({
      'font-size': ((el.get_float() -0.1) +'em'),
      'line-height': 'normal',
      'display': '',
    });
	});  // end of ( each )
});	// end of ( font scaling test )
div {
  width: 50%;
  background-color: tomato;
  font-family: 'Arial';
}

h2 {
  white-space: nowrap;
}

h2:nth-child(2) {
  font-style: italic;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="button" id="controller" value="Apply" />
<div>
  <h2>Lorem ipsum dolor</h2>
  <h2>Test String</h2>
  <h2>Sweet Concatenation</h2>
  <h2>Font Scaling</h2>
</div>

Es reduziert im Wesentlichen die Schriftgröße auf 1em und erhöht sich dann um 0,1, bis die maximale Breite erreicht ist.

jsFiddle

7
WoodrowShigeru

suchst du so etwas? =>
http://jsfiddle.net/sijav/dGsC9/4/
http://fiddle.jshell.net/sijav/dGsC9/4/show/
Ich habe flowtype verwendet und es funktioniert super (allerdings ist es js und keine reine css-Lösung)

$('body').flowtype({
 minFont : 10,
 maxFont : 40,
 minimum : 500,
 maximum : 1200,
 fontRatio : 70
});
6
Sijav

Diese Webkomponente ändert die Schriftgröße, sodass die innere Textbreite mit der Containerbreite übereinstimmt. Überprüfen Sie die Demo .

Sie können es so verwenden: 

<full-width-text>Lorem Ipsum</full-width-text>
6
pomber

100% ist relativ zur Basisschriftgröße. Wenn Sie nicht festgelegt haben, wäre dies die Standardeinstellung des Benutzeragenten des Browsers. 

Um den gewünschten Effekt zu erzielen, würde ich ein Stück Javascript verwenden, um die Grundschriftgröße relativ zu den Fenstermaßnahmen anzupassen.

6
scoota269

Fügen Sie dies in Ihrem CSS unten hinzu, und ändern Sie die Breite von 320px für die Stelle, an der Ihr Design anfängt zu brechen:

    @media only screen and (max-width: 320px) {

       body { font-size: 1em; }

    }

Dann geben Sie die Schriftgröße in "px" oder "em" wie gewünscht an.

6
Chunky

Haben Sie versucht, http://simplefocus.com/flowtype/ ?

Dies ist, was ich für meine Websites verwende und perfekt funktioniert hat. Ich hoffe es hilft.

6
Pixel Reaper

Meine eigene Lösung, die auf jQuery basiert, erhöht schrittweise die Schriftgröße, bis der Container eine größere Höhe erhält (was bedeutet, dass er einen Zeilenumbruch hat) .. _. Sie müssen NICHTS über die verwendete Schriftart wissen, alles wird vom Browser erledigt.

Sie können damit auf http://jsfiddle.net/tubededentifrice/u5y15d0L/2/ spielen.

Die Magie geschieht hier:

var setMaxTextSize=function(jElement) {
    //Get and set the font size into data for reuse upon resize
    var fontSize=parseInt(jElement.data(quickFitFontSizeData)) || parseInt(jElement.css("font-size"));
    jElement.data(quickFitFontSizeData,fontSize);

    //Gradually increase font size until the element gets a big increase in height (ie line break)
    var i=0;
    var previousHeight;
    do
    {
        previousHeight=jElement.height();
        jElement.css("font-size",""+(++fontSize)+"px");
    }
    while(i++<300 && jElement.height()-previousHeight<fontSize/2)

    //Finally, go back before the increase in height and set the element as resized by adding quickFitSetClass
    fontSize-=1;
    jElement.addClass(quickFitSetClass).css("font-size",""+fontSize+"px");

    return fontSize;
};
6
Vincent

Ich habe eine einfache Skalierungsfunktion vorbereitet, die css transform anstelle von Schriftgröße verwendet. Sie können es in jedem Container verwenden, Sie müssen keine Medienabfragen festlegen usw. :)

Blog Post: https://blog.polarbits.co/2017/03/07/full-width-css-js-scalable-header/

Der Code:

function scaleHeader() {
  var scalable = document.querySelectorAll('.scale--js');
  var margin = 10;
  for (var i = 0; i < scalable.length; i++) {
    var scalableContainer = scalable[i].parentNode;
    scalable[i].style.transform = 'scale(1)';
    var scalableContainerWidth = scalableContainer.offsetWidth - margin;
    var scalableWidth = scalable[i].offsetWidth;
    scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
    scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
  }
}

Arbeitsdemo: https://codepen.io/maciejkorsan/pen/BWLryj

5
Maciej Korsan

Mein Problem war ähnlich, bezog sich jedoch auf das Skalieren von Text innerhalb einer Überschrift. Ich habe Fit Font ausprobiert, aber ich musste den Kompressor umschalten, um Ergebnisse zu erhalten, da er ein etwas anderes Problem löste, wie auch Text Flow. Also habe ich mein eigenes kleines Plugin geschrieben, das die Schriftgröße an den Container anpasst, vorausgesetzt, Sie haben overflow: hidden und white-space: nowrap, so dass selbst wenn die Schrift auf ein Minimum reduziert wird, nicht die vollständige Überschrift angezeigt wird, wird nur die Anzeige abgeschnitten .

(function($) {

  // Reduces the size of text in the element to fit the parent.
  $.fn.reduceTextSize = function(options) {
    options = $.extend({
      minFontSize: 10
    }, options);

    function checkWidth(em) {
      var $em = $(em);
      var oldPosition = $em.css('position');
      $em.css('position', 'absolute');
      var width = $em.width();
      $em.css('position', oldPosition);
      return width;
    }

    return this.each(function(){
      var $this = $(this);
      var $parent = $this.parent();
      var prevFontSize;
      while (checkWidth($this) > $parent.width()) {
        var currentFontSize = parseInt($this.css('font-size').replace('px', ''));
        // Stop looping if min font size reached, or font size did not change last iteration.
        if (isNaN(currentFontSize) || currentFontSize <= options.minFontSize ||
            prevFontSize && prevFontSize == currentFontSize) {
          break;
        }
        prevFontSize = currentFontSize;
        $this.css('font-size', (currentFontSize - 1) + 'px');
      }
    });

  };

})(jQuery);
5
Aram Kocharyan

schauen Sie sich meinen Code an, und machen Sie den font size smaller in fit, was auch immer dort ist

aber ich denke, dass dies nicht zu einer guten Benutzererfahrung geführt hat

var containerWidth = $("#ui-id-2").width();
var items = $(".quickSearchAutocomplete .ui-menu-item");
var fontSize = 16;

items.each(function(){
    //display value depend sometimes on your case you may make it block or inline-table instead of inline-block or whatever value that make the div take overflow width
    $(this).css({"whiteSpace":"nowrap","display":"inline-block"});
    while ($(this).width() > containerWidth){
         console.log("$(this).width()"+ $(this).width() + "containerWidth" + containerWidth)
         $(this).css("font-size", fontSize -= 0.5);
    }
});

 result

hoffe das hilft dir

3

Das hat für mich funktioniert:

Ich versuche, die Schriftgröße basierend auf einer Breite/Höhe zu bestimmen, die durch das Einstellen der Schriftgröße erhalten wurde: 10px. Grundsätzlich ist die Idee "wenn ich 20px Breite und 11px Höhe mit Schriftgröße: 10px habe. Was wäre also die maximale Schriftgröße, um einen Container mit 50px Breite und 30px Höhe zu berechnen?"

Die Antwort ist ein Doppelproportionssystem:

{20: 10 = 50: X, 11: 10 = 30: Y} = {X = (10 · 50)/20, Y = (10 · 30)/11}

Jetzt ist X eine Schriftgröße, die der Breite entspricht, Y ist eine Schriftgröße, die der Höhe entspricht. nimm den kleinsten Wert

function getMaxFontSizeApprox(el){
    var fontSize = 10;
    var p = el.parentNode;

    var parent_h = p.offsetHeight ? p.offsetHeight : p.style.pixelHeight;
    if(!parent_h)parent_h = 0;

    var parent_w = p.offsetHeight ? p.offsetWidth : p.style.pixelWidth;
    if(!parent_w)parent_w = 0;

    el.style.fontSize = fontSize + "px";

    var el_h = el.offsetHeight ? el.offsetHeight : el.style.pixelHeight;
    if(!el_h)el_h = 0;

    var el_w = el.offsetHeight ? el.offsetWidth : el.style.pixelWidth;
    if(!el_w)el_w = 0;

    //0.5 is the error on the measure that js does
    //if real measure had been 12.49 px => js would have said 12px
    //so we think about the worst case when could have, we add 0.5 to 
    //compensate the round error
    var fs1 = (fontSize*(parent_w + 0.5))/(el_w + 0.5);
    var fs2 = (fontSize*(parent_h) + 0.5)/(el_h + 0.5);

    fontSize = Math.floor(Math.min(fs1,fs2));
    el.style.fontSize = fontSize + "px";
    return fontSize;
}

Hinweis: Das Argument der Funktion muss ein span-Element oder ein Element sein, das kleiner als das übergeordnete Element ist. Andernfalls schlagen die beiden Funktionen der Funktion width/height fehl, wenn untergeordnete Elemente und übergeordnete Elemente vorhanden sind

2
Maurizio Ricci

Als JavaScript-Fallback (oder Ihre einzige Lösung) können Sie mein jQuery Scalem-Plugin verwenden, mit dem Sie relativ zum übergeordneten Element (Container) skalieren können, indem Sie die Option reference übergeben.

2
thdoan

Für dynamischen Text ist dieses Plugin sehr nützlich http://freqdec.github.io/slabText/ . Fügen Sie einfach css hinzu

.slabtexted .slabtext
    {
    display: -moz-inline-box;
    display: inline-block;
    white-space: nowrap;
    }
.slabtextinactive .slabtext
    {
    display: inline;
    white-space: normal;
    font-size: 1em !important;
    letter-spacing: inherit !important;
    Word-spacing: inherit !important;
    *letter-spacing: normal !important;
    *Word-spacing: normal !important;
    }
.slabtextdone .slabtext
    {
    display: block;
    }

und Skript

$('#mydiv').slabText();
2
pajouk

Falls es für irgendjemanden hilfreich ist, haben die meisten Lösungen in diesem Thread Text in mehrere Zeilen eingeschlossen, Formular e.

Aber dann habe ich das gefunden und es hat funktioniert:

https://github.com/chunksnbits/jquery-quickfit

Anwendungsbeispiel:

$('.someText').quickfit({max:50,tolerance:.4})

2
pk1557

Verwenden Sie fitText plugin, da Viewport-Größen nicht die Lösung dieses Problems sind .. Fügen Sie einfach eine Bibliothek hinzu

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script src="jquery.fittext.js"></script>

und ändern Sie die Schriftgröße für die Korrektur, indem Sie den Textkoeffizienten einstellen:

$("#text_div").fitText(0.8);

sie können Max- und Min-Werte für Text festlegen:

$("#text_div").fitText(0.8, { minFontSize: '12px', maxFontSize: '36px' });
2
dsb

Haben Sie immer Ihr Element mit diesem Attribut:

Javascript: element.style.fontSize = "100%";

oder

CSS: style = "font-size: 100%;"

Wenn Sie in den Vollbildmodus wechseln, sollten Sie bereits eine scalevariable berechnet haben (scale> 1 oder scale = 1). Dann im Vollbildmodus:

document.body.style.fontSize = (scale * 100) + "%";

Es funktioniert gut mit wenig Code.

2
marirena

Verwenden Sie CSS-Variablen

Bisher hat noch niemand CSS-Variablen erwähnt, und dieser Ansatz hat für mich am besten funktioniert.

Angenommen, Sie haben auf Ihrer Seite eine Spalte, die 100% der Bildschirmbreite eines mobilen Benutzers entspricht, aber einen max-width von 800 Pixeln hat. Auf dem Desktop ist auf beiden Seiten der Spalte etwas Platz. Fügen Sie dies oben auf Ihrer Seite ein:

<script> document.documentElement.style.setProperty('--column-width', Math.min(window.innerWidth, 800)+'px'); </script>

Jetzt können Sie diese Variable (anstelle der integrierten Einheit vw) verwenden, um die Größe Ihrer Schrift festzulegen. Z.B.

p {
  font-size: calc( var(--column-width) / 100 );
}

Es ist kein pure CSS-Ansatz, aber es ist ziemlich nahe.

1
user993683

Um die Schriftgröße an den Container anzupassen, sehen Sie anstelle der Fenster die resizeFont()-Funktion, die ich an dieser Frage teilte (eine Kombination aus anderen Antworten, von denen die meisten hier bereits verlinkt sind). Es wird mit window.addEventListener('resize', resizeFont); ausgelöst.

Vanilla JS: Ändern Sie die Größe der Schriftart, um sie an den Container anzupassen

JS:

function resizeFont() {
  var elements  = document.getElementsByClassName('resize');
  console.log(elements);
  if (elements.length < 0) {
    return;
  }
  _len = elements.length;
  for (_i = 0; _i < _len; _i++) {
    var el = elements[_i];
    el.style.fontSize = "100%";
    for (var size = 100; el.scrollHeight > el.clientHeight; size -= 10) {
      el.style.fontSize = size + '%';
    }
  }
}

Sie können vw/vh möglicherweise als Fallback verwenden, sodass Sie em- oder rem-Einheiten dynamisch mithilfe von Javascript zuweisen. Dadurch wird sichergestellt, dass die Schriftarten für das Fenster skaliert werden, wenn Javascript deaktiviert ist.

Wenden Sie die Klasse .resize auf alle Elemente an, die Text enthalten, der skaliert werden soll.

Lösen Sie die Funktion aus, bevor Sie den Ereignislistener für die Fenstergröße hinzufügen. Text, der nicht in den Container passt, wird beim Laden der Seite sowie bei der Größenänderung verkleinert.

HINWEIS: Der Standard font-size muss entweder auf em, rem oder % eingestellt sein, um korrekte Ergebnisse zu erzielen.

1
Joshua Flood

Ich sehe keine Antwort in Bezug auf die Eigenschaft "CSS flex", aber sie kann auch sehr nützlich sein.

1
Smart Coder

html

<div style="height:100px; width:200px;">
  <div id='qwe'>
    test
  </div>
</div>

js für maximale Schriftgröße

 el = document.getElementById('qwe');        
 maxFontPixels = 50;
    maxHeight = el.parentElement.offsetHeight;
    fontSize = Number(maxFontPixels || maxHeight);
    el.style.width = '100%';
    el.style.overflowWrap = 'break-Word';
    var minFS = 3, maxFS = fontSize;
    while (fontSize != minFS) {
      el.style.fontSize = `${fontSize}px`;
      if (el.offsetHeight < maxHeight) {
        minFS = fontSize;
      } else{
        maxFS = fontSize;
      }
      fontSize = Math.floor((minFS + maxFS)/2);
    }
    el.style.fontSize = `${minFS}px`;
0
Ramil Gilfanov

Unmittelbare Medienabfragen scheinen eine viel einfachere und verständlichere Lösung für die Größenänderung von Schriftarten zu sein, die auf den Containergrößen basieren, die möglicherweise dynamisch sind.

Im Folgenden wird die Schriftgröße an die Größe des Containers angepasst, unabhängig davon, ob der Container auf die Größe des Ansichtsfensters skaliert wird oder ob er den Maximalwert erreicht hat. Wenn Sie nicht zu 100% breite Container haben, können Sie die vw entsprechend anpassen.

.container {
    width: 100%;
    max-width: 600px;
}
.headline {
    font-size: 20vw;
}
.subhead {
    font-size: 5vw;
}
@media (min-width:600px) {
    .headline {
        font-size: 120px;
    }
    .subhead {
        font-size: 32px;
    }
}
0
Justin Krause

Aber was ist, wenn der Container nicht der Darstellungsbereich (Körper) ist?

Die wahre Antwort ist in der transform -Eigenschaft, mit der Sie ein Element visuell bearbeiten können, indem Sie es verzerren, drehen, verschieben oder skalieren:

https://css-tricks.com/almanac/properties/t/transform/

0
Crystal