Viewport-Einheiten gibt es nun schon seit einigen Jahren, mit nahezu perfekter Unterstützung in den gängigen Browsern, aber ich entdecke immer wieder neue und spannende Wege, sie zu nutzen. Ich dachte, es wäre eine gute Idee, die Grundlagen zu wiederholen und dann einige meiner Lieblingsanwendungsfälle zusammenzufassen.
Was sind Viewport-Einheiten?
Vier neue „viewport-relative“ Einheiten erschienen zwischen 2011 und 2015 in den CSS-Spezifikationen als Teil des CSS Values and Units Module Level 3 des W3C. Die neuen Einheiten – vw, vh, vmin und vmax – funktionieren ähnlich wie bestehende Längeneinheiten wie px oder em, stellen aber einen Prozentsatz des aktuellen Browser-Viewports dar.
- Viewport-Breite (
vw) – Ein Prozentsatz der vollen Viewport-Breite.10vwwird zu 10 % der aktuellen Viewport-Breite aufgelöst, oder48pxauf einem Telefon mit480pxBreite. Der Unterschied zwischen%undvwähnelt am ehesten dem Unterschied zwischenemundrem. Eine%-Länge bezieht sich auf die Breite des lokalen Kontexts (des umschließenden Elements), während einevw-Länge sich auf die volle Breite des Browserfensters bezieht. - Viewport-Höhe (
vh) – Ein Prozentsatz der vollen Viewport-Höhe.10vhwird zu10%der aktuellen Viewport-Höhe aufgelöst. - Viewport-Minimum (
vmin) – Ein Prozentsatz der Viewport-Breite oder -Höhe, welcher auch immer kleiner ist.10vminwird zu 10 % der aktuellen Viewport-Breite in Hochformatausrichtung und zu 10 % der Viewport-Höhe in Querformatausrichtung aufgelöst. - Viewport-Maximum (
vmax) – Ein Prozentsatz der Viewport-Breite oder -Höhe, welcher auch immer größer ist.10vmaxwird zu 10 % der aktuellen Viewport-Höhe in Hochformatausrichtung und zu 10 % der Viewport-Breite in Querformatausrichtung aufgelöst. Leider und seltsamerweise sindvmax-Einheiten im Internet Explorer oder Edge noch nicht verfügbar.
Obwohl diese Einheiten aus der Viewport-Höhe oder -Breite abgeleitet sind, können sie überall dort verwendet werden, wo Längen akzeptiert werden – von font-size bis hin zu Positionierung, Margins, Padding, Schatten, Rändern und so weiter. Lassen Sie uns sehen, was wir tun können!
Responsive Typografie
Es ist sehr beliebt geworden, Viewport-Einheiten für responsive Typografie zu verwenden – um Schriftgrößen festzulegen, die je nach aktueller Viewport-Größe wachsen und schrumpfen. Die Verwendung einfacher Viewport-Einheiten für die Schriftgröße hat einen interessanten (gefährlichen) Effekt. Wie Sie sehen können, skalieren Schriftarten sehr schnell – sie passen sich in einem sehr kleinen Bereich von unleserlich klein bis extra groß an.

Diese direkte Skalierung ist eindeutig zu dramatisch für den täglichen Gebrauch. Wir brauchen etwas Subtileres, mit Minima und Maxima und mehr Kontrolle über die Wachstumsrate. Hier wird calc() nützlich. Wir können eine Grundgröße in stabileren Einheiten (z. B. 16px) mit einer kleineren viewport-relativen Anpassung (0.5vw) kombinieren und den Browser die Berechnung durchführen lassen: calc(16px + 0.5vw)
Indem Sie das Verhältnis zwischen Ihrer Grundgröße und der viewport-relativen Anpassung ändern, können Sie die dramatische Wachstumsrate ändern. Verwenden Sie höhere Viewport-Werte für Überschriften und beobachten Sie, wie sie schneller wachsen als der umliegende Text. Dies ermöglicht eine dynamischere typografische Skala auf größeren Bildschirmen, während die Schriftarten auf einem mobilen Gerät eingeschränkt bleiben – keine Media Queries erforderlich. Sie können diese Technik auch auf Ihre line-height anwenden, sodass Sie den Zeilenabstand in einem anderen Verhältnis als die font-size anpassen können.
body {
// font grows 1px for every 100px of viewport width
font-size: calc(16px + 1vw);
// leading grows along with font,
// with an additional 0.1em + 0.5px per 100px of the viewport
line-height: calc(1.1em + 0.5vw);
}
Für mich ist das ausreichend komplex. Wenn ich das obere Ende für schnell wachsende Überschriften einschränken muss, kann ich das mit einer einzigen Media-Query tun, wo auch immer der Text zu groß wird.
h1 {
font-size: calc(1.2em + 3vw);
}
@media (min-width: 50em) {
h1 {
font-size: 50px;
}
}
Plötzlich wünschte ich, es gäbe eine max-font-size-Eigenschaft.
Andere haben komplexere Berechnungen und Sass-Mixins entwickelt, um genaue Textgrößenbereiche bei bestimmten Media Queries anzugeben. Es gibt mehrere bestehende Artikel auf CSS-Tricks, die die Technik erklären und Snippets bereitstellen, um Ihnen den Einstieg zu erleichtern.
- Viewport-basierte Typografie mit Mindest- und Maximalgrößen
- Flüssige Typografie
- The Math of CSS locks
Ich denke, das ist in den meisten Fällen übertrieben, aber Ihre Ergebnisse können absolut variieren.
Layouts in voller Höhe, Hero-Bilder und Sticky Footer
Es gibt viele Variationen von Full-Height (oder höhenbeschränkten) Layouts – von Desktop-ähnlichen Schnittstellen bis hin zu Hero-Bildern, geräumigen Designs und Sticky Footer. Viewport-Einheiten können bei all diesen helfen.
In einer Desktop-ähnlichen Full-Height-Oberfläche ist die Seite oft in Abschnitte unterteilt, die einzeln scrollen – mit Elementen wie Kopfzeilen, Fußzeilen und Seitenleisten, die bei jeder Größe an Ort und Stelle bleiben. Dies ist heutzutage üblich für viele Web-Apps, und vh-Einheiten machen es viel einfacher. Hier ist ein Beispiel, das die neue CSS Grid-Syntax verwendet.
Siehe den Pen Full-height CSS Grid von Miriam Suzanne (@mirisuzanne) auf CodePen.
Eine einzige Deklaration auf dem body-Element, height: 100vh, begrenzt Ihre Anwendung auf die Höhe des Viewports. Stellen Sie sicher, dass Sie overflow-Werte für interne Elemente anwenden, damit Ihr Inhalt nicht abgeschnitten wird. Sie können dieses Layout auch mit Flexbox oder Floats erreichen. Beachten Sie, dass Full-Height-Layouts auf einigen mobilen Browsern Probleme verursachen können. Es gibt eine clevere Lösung für iOs Safari, die wir verwenden, um einen der auffälligsten Randfälle zu behandeln.
Sticky-Footer können mit einer ähnlichen Technik erstellt werden. Ändern Sie height: 100vh des Bodys zu min-height: 100vh, und der Footer bleibt am unteren Bildschirmrand, bis er durch Inhalt nach unten geschoben wird.
Siehe den Pen Sticky-Footer mit CSS Grid von Miriam Suzanne (@mirisuzanne) auf CodePen.
Wenden Sie vh-Einheiten auf die height, min-height oder max-height verschiedener Elemente an, um ganze Bildschirmabschnitte, Hero-Bilder und mehr zu erstellen. Im neuen OddBird-Redesign haben wir unsere Hero-Bilder mit max-height: 55vh begrenzt, damit sie die Überschriften nicht vom Bildschirm verdrängen. Auf meiner persönlichen Website habe ich mich für max-height: 85vh entschieden, für einen stärker bildorientierten Look. Auf anderen Websites habe ich min-height: 90vh auf Abschnitte angewendet.
Hier ist ein Beispiel, das sowohl einen heroischen Kätzchen mit max-height als auch einen Abschnitt mit min-height zeigt. Die Kombination all dieser Tricks kann Ihnen mächtige Kontrolle darüber geben, wie Ihr Inhalt ein Browserfenster füllt und wie er auf verschiedene Viewports reagiert.
Fließende Seitenverhältnisse
Es kann auch nützlich sein, das Seitenverhältnis eines Elements zu begrenzen. Dies ist besonders nützlich für eingebettete Inhalte wie Videos. Chris hat bereits darüber geschrieben. In guten alten Zeiten haben wir das mit prozentbasiertem Padding auf einem Container-Element und absoluter Positionierung auf dem inneren Element gemacht. Jetzt können wir manchmal Viewport-Einheiten verwenden, um diesen Effekt ohne zusätzliche Markup zu erzielen.
Wenn wir davon ausgehen können, dass das Video Vollbild ist, können wir die Höhe relativ zur vollen Viewport-Breite einstellen.
/* full-width * aspect-ratio */
.full-width {
width: 100vw;
height: calc(100vw * (9/16));
}
Diese Berechnung muss nicht im Browser mit calc erfolgen. Wenn Sie einen Pre-Prozessor wie Sass verwenden, funktioniert die Berechnung auch dort: height: 100vw * (9/16). Wenn Sie die maximale Breite begrenzen müssen, können Sie auch die maximale Höhe begrenzen.
/* max-width * aspect-ratio */
.full-width {
width: 100vw;
max-width: 30em;
height: calc(100vw * (9/16));
max-height: calc(30em * (9/16));
}
Hier ist eine Demonstration, die beide Optionen zeigt, mit CSS-Custom-Properties (Variablen), um die Berechnung semantischer zu gestalten. Spielen Sie mit den Zahlen, um zu sehen, wie sich die Dinge bewegen und jederzeit das richtige Verhältnis beibehalten.
Siehe den Pen Fluid Ratios with Viewport Units von Miriam Suzanne (@mirisuzanne) auf CodePen.
Chris geht in seinem Artikel vor Viewport-Einheiten einen Schritt weiter, und das werden wir auch tun. Was ist, wenn wir tatsächliche HTML-Inhalte benötigen, die sich innerhalb eines bestimmten Verhältnisses skalieren – wie es Präsentationsfolien oft tun?
Wir können alle internen Schriftarten und Größen mit denselben Viewport-Einheiten wie der Container einstellen. In diesem Fall habe ich vmin für alles verwendet, sodass sich der Inhalt mit Änderungen sowohl der Container-Höhe als auch der -Breite skaliert.
Siehe den Pen Fluid Slide Ratios with Viewport Units von Miriam Suzanne (@mirisuzanne) auf CodePen.
Den Container sprengen
Seit Jahren ist es beliebt, eingeschränkten Text mit Vollbild-Hintergründen zu mischen. Abhängig von Ihrem Markup oder CMS kann dies schwierig werden. Wie bricht man Inhalte aus einem eingeschränkten Container aus, so dass sie exakt den Viewport ausfüllen?
Auch hier können Viewport-Einheiten nützlich sein. Dies ist ein weiterer Trick, den wir auf der neuen OddBird-Website verwendet haben, wo ein Static-Site-Generator manchmal unsere Kontrolle über das Markup einschränkt. Es bedarf nur weniger Codezeilen, um dies zu ermöglichen.
.full-width {
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
}
Es gibt ausführlichere Artikel über die Technik, sowohl bei Cloud Four als auch hier auf CSS Tricks.
Sonderbare Dinge tun
Natürlich können Sie mit Viewport-Einheiten noch viel mehr machen, wenn Sie anfangen zu experimentieren. Schauen Sie sich diesen reinen CSS-Scroll-Indikator an (von jemandem namens Mike) unter Verwendung von Viewport-Einheiten auf einem Hintergrundbild.
Siehe den Pen CSS only scroll indicator von Mike (@MadeByMike) auf CodePen.
Was haben Sie sonst noch mit Viewport-Einheiten gesehen oder gemacht? Werden Sie kreativ und zeigen Sie uns die Ergebnisse!
Scroll Indicator ist reines Wahnsinn :)
Stimme zu!
Stimme zu!
In der Tat
Tolle Inhalte. Viewport ist sehr nützlich für Responsive Webdesign, hilfreicher Artikel. Danke.
vw und vh sind super! Obwohl iOS 10* und die neueste Facebook App Webview derzeit einige Probleme mit 100vh haben, das größer als innerHeight ist, so dass Full-Page-Web-Apps vom unteren Bildschirmrand verschwinden.
Dies scheint den Trick zu tun, um es zu beheben: https://stackoverflow.com/questions/35421247/wrong-viewport-page-height-in-embedded-facebook-browser-in-ios-9-x
Können Sie uns erklären, wie der Scroll-Indikator funktioniert? Ist es nur ein Dreieck-Gradient, der von
body::beforeabgedeckt wird, welches mitz-index: -1sauber zwischen dem Gradienten und dem Inhalt liegt?Das ist genau richtig. Das Dreieck wird so erstellt:
100%) abzüglich der Höhe des Fensters (100vh) unterhalb der Kopfzeile (129px) beträgt. Dies begrenzt die Höhe des Dreiecks etwas, da die Scrollleiste am oberen Rand der Seite ist und man nie wirklich bis zum Ende scrollen kann.Toller Artikel, Miriam. Hier ist, was ich in letzter Zeit mit Viewport-Einheiten mache: Sie mit linearen Gleichungen und Breakpoints mischen: Poly Fluid Sizing (https://www.smashingmagazine.com/2017/05/fluid-responsive-typography-css-poly-fluid-sizing/)
In einem verwandten Thema ist ein Nachteil der Verwendung von Viewport-Einheiten für
font-size, dass sie nicht zugänglich sind. Das Ändern der Browser-Textgröße wird für alles ignoriert, das gerade Viewport-Einheiten verwendet. Sie skalieren, wenn Sie Viewport-Einheiten in einercalc()verwenden, aber ihre Änderungsrate hängt von Ihrem Pixelwert ab, der in der Gleichung verwendet wird.Abgesehen von diesem Nachteil sind Viewport-Einheiten ziemlich großartig!
Toller Artikel! Ich bin so frustriert, dass Browser bei CSS/HTML-Spezifikationen, die seit Jahren existieren, nicht mithalten. Man muss immer jahrelang warten, um die coolen Funktionen und Werkzeuge zu implementieren, die wir gestern schon brauchten. Danke, Miriam, das wird als Lesezeichen gespeichert.
Können Viewport-Einheiten verwendet werden, um einen Parallax-Effekt mit Hintergrundbildern zu erzeugen (ähnlich dem Scroll-Indikator-Beispiel)?
Hallo Miriam,
Danke für diesen Artikel.
Sie erwähnen calc oder sass für fließende Seitenverhältnisse, aber ich denke, keines von beiden ist für diese Berechnungen erforderlich. Könnten wir nicht einfach Folgendes schreiben?
Sicher, das funktioniert auch. Ich bevorzuge es immer, meine Berechnungen mit möglichst vielen semantischen Hinweisen (wie Variablennamen) anzuzeigen, anstatt eine zufällig aussehende Zahl wie
56,25einzufügen. Ich möchte, dass der Code aussagekräftig und lesbar ist, zusätzlich zur Funktionalität. Ihre Kommentare machen etwas Ähnliches – fügen ein paar Hinweise hinzu, und Sie könnten mehr hinzufügen – aber warum nicht die Berechnung direkt im Code sichtbar machen?Oh, das ergibt Sinn. Meine Logik war,
calc()zu vermeiden, wenn es nicht benötigt wird, um den Code zugänglicher (arme Opera Mini-Benutzer!) und performanter zu machen (obwohl ich keine Ahnung von den Leistungskosten der Verwendung von calc() habe...). Aber dann, wie Sie sagen, erfordert es die zusätzlichen Kommentare...Momentan scheint es einen Bug in Safari 10.1 zu geben, der das fließende Ändern von Schriftgrößenwerten, die eine calc()-Funktion mit einer Viewport-Einheit als Wert in der Funktion enthalten, nicht unterstützt. Dies beeinträchtigt natürlich keine mobilen Benutzer, aber es ist definitiv ärgerlich für diejenigen, die ihr Browserfenster mit Safari unter macOS vergrößern möchten. Ich habe diesen Fehler an Apple gemeldet, also werden wir sehen, ob etwas getan werden kann.
In Ihrem Sticky-Footer-Beispiel haben Sie die Spaltenwerte wie folgt eingestellt:
grid-template-columns: minmax(auto, 12em) 5fr;
Was bedeutet in dieser Zeile die 5fr-Einheit? Denn wenn wir sie auf 1fr setzen, ändert sich nichts!
Ja, das würde dort keinen Unterschied machen, da dies die einzigen „Fraktionen“ sind, die verwendet werden. Es könnten 999999fr sein und es wäre dasselbe, weil 999999/999999 = 1, genau wie 5/5 = 1 oder 1/1 = 1.
Ha, ja. Gut erwischt. Ich glaube, ich habe anfangs
fr-Einheiten für die Seitenleiste verwendet und die Hauptbreite nie geändert, nachdem ich zuautoundems gewechselt bin.Die meisten davon funktionieren nicht mit IE oder Edge, daher ist ihre Nützlichkeit begrenzt.
Die Nützlichkeit von IE und Edge ist ebenfalls begrenzt.
Wenn Sie Viewport-Einheiten für
font-sizeverwenden, überschreiben Sie die integrierte Fähigkeit des Browsers, den Text zu zoomen. Dies gilt unabhängig davon, ob Sie ihn in einer calc()-Funktion verwenden. Dies bricht die grundlegendste Webzugänglichkeitsfunktion und nimmt Ihren Benutzern die Kontrolle.Die einzige Möglichkeit, wie ein Benutzer Text mit Viewport-Einheiten skalieren kann, ist die Änderung der Viewport-Größe. Dies scheint zufällig zu sein und funktioniert in vielen Fällen nicht.
Bitte brechen Sie mein Zoom nicht!
Bitte ignorieren Sie meinen Kommentar – ich habe mich wohl missverstanden. Wenn Sie
font-sizemit einer calc-Funktion mit vw und px oder em definieren, funktioniert die normale Browser-Skalierung einwandfrei.„oder 48px auf einem Telefon mit 480px Breite“ ===》„oder 48vx auf einem Telefon mit 480px Breite“