Spaß mit Viewport-Einheiten

Avatar of Miriam Suzanne
Miriam Suzanne am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

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. 10vw wird zu 10 % der aktuellen Viewport-Breite aufgelöst, oder 48px auf einem Telefon mit 480px Breite. Der Unterschied zwischen % und vw ähnelt am ehesten dem Unterschied zwischen em und rem. Eine %-Länge bezieht sich auf die Breite des lokalen Kontexts (des umschließenden Elements), während eine vw-Länge sich auf die volle Breite des Browserfensters bezieht.
  • Viewport-Höhe (vh) – Ein Prozentsatz der vollen Viewport-Höhe. 10vh wird zu 10% der aktuellen Viewport-Höhe aufgelöst. 
  • Viewport-Minimum (vmin) – Ein Prozentsatz der Viewport-Breite oder -Höhe, welcher auch immer kleiner ist. 10vmin wird 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. 10vmax wird zu 10 % der aktuellen Viewport-Höhe in Hochformatausrichtung und zu 10 % der Viewport-Breite in Querformatausrichtung aufgelöst. Leider und seltsamerweise sind vmax-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.

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!