Frage Font-Skalierung basierend auf der Containerbreite


Es fällt mir schwer, mich mit der Schriftgröße vertraut zu machen.

Das habe ich gerade Diese Seite mit einem Körper font-size von 100%. 100% was aber? Dies scheint bei 16px zu berechnen.

Ich hatte den Eindruck, dass sich 100% irgendwie auf die Größe des Browserfensters beziehen würde, aber anscheinend nicht, weil es immer 16px ist, ob das Fenster auf eine mobile Breite oder einen Vollbild-Desktop verkleinert wird.

Wie kann ich den Text auf meiner Website in Bezug auf den Container skalieren? Ich habe es versucht em aber das skaliert auch nicht.

Mein Argument ist, dass Dinge wie mein Menü bei der Größenanpassung zerquetscht werden, also muss ich den px verkleinern font-size von .menuItem unter anderem in Bezug auf die Breite des Containers. (Z. B. im Menü auf einem großen Desktop, funktioniert 22px perfekt. Bewegen Sie sich nach unten auf Tablet-Breite und 16px ist besser geeignet.)

Ich bin mir bewusst, dass ich Breakpoints hinzufügen kann, aber ich möchte wirklich, dass der Text skaliert wird, genauso wie zusätzliche Breakpoints, sonst werde ich mit Hunderten von Breakpoints für jede 100px Verringerung der Breite enden, um den Text zu kontrollieren.


808
2018-04-17 09:37


Ursprung


Antworten:


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

Wenn der Behälter der Körper ist, wonach Sie suchen Viewport-prozentuale Längen:

Das Ansichtsfenster-Prozentlängen sind relativ zur Größe der Anfangs enthaltender Block. Wenn die Höhe oder Breite des ursprünglichen umschließenden Blocks geändert wird, werden sie entsprechend skaliert. Wenn der Wert des Überlaufs für das Stammelement jedoch auto ist, wird davon ausgegangen, dass keine Bildlaufleisten existieren.

Die Werte sind:

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

1 v * entspricht 1% des ursprünglichen umschließenden Blocks.

es sieht so aus:

p {
    font-size: 4vw;
}

Wie Sie sehen, erhöht sich die Breite des Darstellungsbereichs ebenso wie die Schriftgröße, ohne dass Medienabfragen verwendet werden müssen.

Diese Werte sind wie eine Größeneinheit px oder em, so dass sie auch zur Größenanpassung anderer Elemente verwendet werden können, z. B. Breite, Rand oder Füllung.

Browser-Unterstützung ist ziemlich gut, aber Sie werden wahrscheinlich ein Fallback benötigen, wie:

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

Schau dir die Support-Statistiken an: http://caniuse.com/#feat=viewport-einheiten.

Schauen Sie sich auch CSS-Tricks für einen breiteren Blick an: http://css-tricks.com/viewport-sized-typography/

Hier ist ein schöner Artikel über das Einstellen von Min / Max-Größen und etwas mehr Kontrolle über die Größen: http://madebymike.com.au/writing/precise-control-responsive-typography/

Und hier ist ein Artikel über die Einstellung der Größe mit calc (), so dass der Text das Ansichtsfenster füllt: http://codepen.io/CrocoDillon/pen/fBJxu

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


1172
2017-11-06 14:40



Was aber, wenn der Container nicht das Viewport (Body) ist?

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

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

Beispiel 1

Bei einem flexiblen Breitenbehälter muss jedoch erkannt werden, dass sich der Behälter in gewisser Weise befindet Größe wird immer noch vom Ansichtsfenster entfernt. Daher ist es eine Frage der Anpassung eines vw Die Einstellung basiert auf dem prozentualen Größenunterschied zum Ansichtsfenster, was bedeutet, dass die Größe der übergeordneten Wrapper berücksichtigt wird. Nimm 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, hier div ist ein Kind der body, es ist 50% davon 100% Breite, die die Größe des Darstellungsbereichs in diesem grundlegenden Fall ist. Grundsätzlich möchten Sie ein vw das wird dir gut aussehen. Wie Sie in meinem Kommentar im obigen css sehen können, können Sie das mathematisch in Bezug auf die gesamte Größe des Darstellungsbereichs "durchdenken", aber Sie nicht brauchen das zu tun. Der Text wird mit dem Container "gebogen", da sich der Container mit der Größenänderung des Ansichtsfensters bewegt. AKTUALISIEREN: Hier ist ein Beispiel für zwei unterschiedlich große Container.

Beispiel 2

Sie können dabei helfen, die Größe des Ansichtsfensters sicherzustellen, indem Sie die Berechnung basierend darauf 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 200% 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 Bemaßung basiert immer noch auf dem Ansichtsfenster, ist aber im Wesentlichen basierend auf der Containergröße selbst eingerichtet.

Soll die Größenänderung des Containers dynamisch geändert werden?

Wenn sich die Dimensionierung des Containerelements geändert hat, ändert sich seine prozentuale Beziehung entweder dynamisch über @media break points oder via Javascript, dann müsste, was auch immer das "Ziel" der Basis war, eine Neuberechnung erforderlich sein, um dieselbe "Beziehung" für die Textgröße beizubehalten.

Nehmen Sie Beispiel 1 oben. Wenn die div war eingeschaltet 25% Breite von beiden @media oder Javascript, dann zur gleichen Zeit, die font-size müsste entweder die media query oder per javascript an die neue berechnung von anpassen 5vw * .25 = 1.25. Dies würde die Textgröße auf die gleiche Größe bringen, die die "Breite" des Originals hätte 50% Container wurde um die Hälfte von Viewport Sizing reduziert, wurde aber jetzt aufgrund einer Änderung in seiner eigenen Prozentberechnung reduziert.

Eine Herausforderung

Mit das CSS3 calc() Funktion Im Einsatz würde es schwierig werden, dynamisch anzupassen, da diese Funktion nicht funktioniert font-sizeZwecke zu dieser Zeit. Sie können also keine reine CSS3-Anpassung vornehmen, wenn sich Ihre Breite ändert calc(). Natürlich kann eine geringfügige Anpassung der Breite für die Ränder nicht ausreichen, um eine Änderung zu rechtfertigen font-sizeEs ist also egal.


249
2017-11-06 16:56



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 das die Frage des Op nicht beantwortet, aber vielleicht kann es eine Lösung für jeden anderen sein.


21
2018-03-11 08:30



Es gibt eine große Philosophie für dieses Problem. Am einfachsten wäre es, dem Körper eine bestimmte Schriftgröße zu geben (ich empfehle 10), und dann würde alle anderen Elemente ihre Schriftart in em oder rem haben. Ich gebe dir und ein Beispiel, um diese Einheiten zu verstehen. Em ist immer relativ zu seinem Elternteil

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 zur Containerbreite ändert. Aber das würde ich nicht empfehlen. Denn in einem Container mit einer Breite von 900 Pixeln hätten Sie beispielsweise eine p Element mit 12px Schriftgröße sagen wir mal. Und auf Ihre ideea, die auf 300px Breite Container bei 4px Schriftgröße würde. Es muss eine untere Grenze geben. Eine andere Lösung wären Medienabfragen, so dass Sie die Schriftart für verschiedene Breiten festlegen können.

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


20
2017-11-11 10:01



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/


19
2018-06-18 16:47



Aktualisiert, weil ich eine Down-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
};

Dann wandeln Sie alle Schriftgrößen Ihrer Dokumente untergeordnete Elemente in ems oder% um.

Fügen Sie dann 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/


18
2018-01-07 09:43



Dies ist vielleicht nicht sehr praktisch, aber wenn Sie wollen, dass font eine direkte Funktion des Elternteils ist, ohne JS, der / loops (interval) lauscht, um die Größe des div / page zu lesen, gibt es eine Möglichkeit, dies zu tun. IFrames. Alles, was im Iframe enthalten ist, berücksichtigt die Größe des Iframes als Größe des Ansichtsfensters. Der Trick besteht also darin, einfach einen Iframe zu erstellen, dessen Breite die maximale Breite ist, die Ihr Text haben soll, und dessen Höhe der maximalen Höhe des Seitenverhältnisses des jeweiligen Textes entspricht.

Abgesehen von der Einschränkung, dass Viewport-Einheiten nicht auch Seiten-Eltern-Einheiten für Text mitkommen können (wie in%), bieten Viewport-Einheiten ein sehr mächtiges Werkzeug: die Min / Max-Dimension zu erhalten . Das kannst du nirgendwo anders machen - du kannst nicht sagen ... mach die Höhe dieses div die Breite des Eltern * etwas.

Davon abgesehen besteht der Trick darin, vmin zu verwenden und die Iframe-Größe so festzulegen, dass die Gesamthöhe eine gute Schriftgröße ist, wenn die Höhe die begrenzende Dimension ist, und die Gesamtbreite, wenn die Breite die 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 mit dieser Methode ist, dass Sie das CSS des iframe manuell einstellen müssen. Wenn Sie die gesamte CSS-Datei anhängen, würde das für viele Textbereiche viel Bandbreite in Anspruch nehmen. Also, was ich tue, ist die Regel, die ich möchte, direkt von meinem CSS anhängen.

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 / alle CSS-Regeln erhält, die den Textbereich beeinflussen würden.

Ich kann mir keinen anderen Weg vorstellen, es ohne JS zu machen. Die wirkliche Lösung wäre, dass Browser eine Möglichkeit bieten, Text als Funktion des übergeordneten Containers zu skalieren UND auch die gleiche vmin / vmax-Typ-Funktionalität bereitzustellen.

JS Geige: https://jsfiddle.net/0jr7rrgm/3/ (Klicken Sie einmal, um das rote Quadrat an der Maus zu fixieren, klicken Sie erneut, um es zu lösen)

Der Großteil der JS in der Geige ist nur meine benutzerdefinierte Click-Drag-Funktion


12
2018-04-12 19:22