Rolf B: Die Neue Responsivität – Webdesign in einer von Komponenten bestimmten Welt

Beitrag lesen

Steuerung von Makro- und Mikro-Layout in einer neuen Ära responsiven Webdesigns

  • Medienabfragen für Benutzereinstellungen
  • Containerabfragen
  • Formfaktor des verwendeten Geräts
  • Scoped Styles

Von Una Kravets, 19.05.2021, veröffentlicht unter https://web.dev/new-responsive/

Übersetzt und bearbeitet für Selfhtml von Rolf B, Juni 2021

Dieser Text wird unter der CC BY 4.0 (Namensnennung 4.0) veröffentlicht.

Die Grafiken und Animationsvideos im Blog stammen von Una Kravets' Seite und sind deshalb auf Englisch.

Vielen Dank an Una Kravets für ihren spannenden Vortrag. Das folgende Video enthält das Original, der Blog-Text ist eine übersetzte und bearbeitete Abschrift davon.

Link zum Originalvideo
Klicken Sie auf das Bild, um den Vortrag bei YouTube im Original anzuschauen.

Responsives Design heute

Wenn Sie heute den Begriff „responsives Design“ verwenden, denken Sie höchstwahrscheinlich an @media-Abfragen, mit denen sich das Layout Ihrer Seiten an die Größe des Viewports anpasst, vom Mobilgerät über ein Tablet bis hin zum Desktop.

@media-Abfragen können neben der Größe und dem Format des Viewports noch weitere Features des genutzten Gerätes überprüfen. Neue Geräteeigenschaften wie z.B. Faltbildschirme machen hierfür neue Abfragen nötig. Und außer dem Gerät gibt es noch ein weiteres Element, mit dem Ihre Webseite konfrontiert ist: die Besucherinnen und Besucher Ihrer Seite mit ihren persönlichen Voreinstellungen, wie Dark Mode oder dem Verzicht auf Animationen.

Aber mit @media-Abfragen stoßen Sie an Grenzen, wenn Sie Komponenten verwenden wollen. Unter einer Komponente verstehen wir hier ein HTML-Element mit beliebigen Kindelementen, das fertig vorliegt und auf Ihrer Seite ein- oder mehrfach genutzt wird. Diese Nutzung kann in unterschiedlichen Container-Elementen stattfinden, und es ist nicht sinnvoll, das Stylesheet für eine Komponente für jede Seite oder jeden Container an das Umfeld anpassen zu müssen. Hier kommen containerbezogene Abfragen ins Spiel, so dass eine Komponente sich – ganz gleich wo sie platziert ist – an ihr Umfeld anpassen und dafür ihren festen Satz an CSS-Regeln mitbringen kann.

Ich spreche hier nicht von Responsivität, die sich mit prozentualen Angaben für eine Größe oder ein Padding erreichen lässt. Gemeint sind weitergehende Anpassungen, wie das Ausblenden bestimmter Elemente oder das Umschalten auf ein anderes Grid-Template. Bis zu einem gewissen Punkt können Sie viewportbasierende @media-Abfragen nutzen, um Ihre Komponente passend zu beeinflussen. Das Problem ist nur, dass diese Abfragen korrekt an den Elterncontainer dieser Komponente angepasst sein müssen. Und wenn der Container Teil eines flexiblen Designs ist, wie einer Flexbox mit aktiviertem flex-wrap, stößt das sehr schnell an Grenzen oder wird immens komplex.

Una Kravets meint, dass containerbasierende Abfragen hier eine deutliche Neuerung sein werden, ähnlich zu dem Unterschied zwischen Grid-Layout und einem Seitenlayout mit <table> Elementen.

Was im Moment auf uns zukommt, ist eine neue Responsivität in Bezug auf drei Themen:

Responsivität zum User, Container und Formfaktor

Responsivität zum Benutzer

Neue Medienfeatures für Benutzereinstellungen geben Ihnen die Möglichkeit, die Styles Ihrer Seite auf die speziellen Bedürfnisse und Voreinstellungen der Besucher*innen ausrichten zu können. Dazu gehören Features wie

  • prefers-reduced-motion
  • prefers-contrast
  • prefers-reduced-transparency
  • prefers-color-scheme
  • inverted-colors
  • und mehr.

Sie können dazu auch den Einstiegsartikel im Self-Wiki lesen.

Diese Medienfeatures fragen Voreinstellungen ab, die im Betriebssystem gesetzt wurden. Sie können damit auf diese Einstellungen im CSS direkt reagieren, ohne dass Ihre Besucher*innen sie auf Ihrer Seite separat setzen müssen. Das ist besonders wertvoll für diejenigen, die auf Accessibility, also erleichterte Bedienung, angewiesen sind.

prefers-reduced-motion

Leute, die im Betriebssystem verringerte Bewegung (Windows: den Schalter „Animationen anzeigen“ ausschalten) eingestellt haben, wünschen weniger Animationen, wenn sie ihren Computer verwenden. Diese Besucher*innen werden also wenig davon halten, einen wuseligen Intro-Bildschirm, Umblätter-Animationen, aufwändige Fortschrittsanzeigen oder andere komplexe Animationen zu sehen.

Mit prefers-reduced-motion können Sie Ihre Seiten so gestalten, dass sich wenig bewegt, und als Progressive Enhancement eine Darstellung mit mehr Bewegung für diejenigen schaffen, die diese Voreinstellung nicht getroffen haben.

Die gezeigten Karten haben Informationen auf beiden Seiten. Die Basis-Darstellung verwendet eine Überblendung von der einen zur anderen Seite, und die Version mit zusätzlicher Bewegung dreht die Karte um.

prefers-reduced-motion sollte nicht als „Gar keine Bewegung“ interpretiert werden, weil Bewegung ein maßgebliches Mittel sein kann, um online Informationen zu übermitteln. Verwenden Sie als Basis-Implementierung eine vernünftige Darstellung, die Ihre Besucher*innen ohne unnötige Bewegungen führt, und erweitern Sie das für diejenigen, die keine besonderen Anforderungen an Zugänglichkeit stellen müssen – oder wollen.

prefers-color-scheme

Die Featureabfrage prefers-color-scheme hilft Ihnen dabei, Ihr UI an das Darstellungsthema anzupassen, das die Benutzer*innen bevorzugen. In heutigen Betriebssystemen, ob Desktop oder Mobil, findet man Einstellmöglichkeiten für ein helles oder dunkles Thema, und Automatiken, die nach Tageszeit das Thema umschalten.

Wenn Sie Ihre Seite mit CSS custom properties gestalten, ist der Austausch von Farbwerten eine einfache Sache. Sie können durch Aktivieren einer anderen CSS-Regel schnell alle Festlegungen für die Farbwerte eines Themas in einer Medienabfrage ersetzen. Matthias Scharwies hat dazu im April einen Blog-Artikel veröffentlicht.

Um das Testen dieser Abfragen auf Einstellungsfeatures zu erleichern, können Sie die Entwicklerwerkzeuge Ihres Browsers verwenden.

In Chrome
Aktivieren Sie das "Rendering"-Tool (im ⋮ Menü unter More Tools) und suchen Sie nach Emulate CSS media feature prefers-color-scheme
In Firefox
Es gibt auf der Inspektor-Seite ein Sonnen- und Mond-Buttons über den CSS-Regeln
In Safari
(wer weiß es?)

Design für ein dunkles Thema

Wenn Sie ein dunkles Thema designen, geht es nicht nur darum, Hintergrund- und Textfarben zu vertauschen und dunkle Scrollbars zu erzeugen. Es gibt weitere Überlegungen, an die man nicht immer denkt. Beispielsweise möchten Sie vielleicht die Sättigung der Farben reduzieren, um visuelle Vibration zu vermindern. (Visuelle Vibration entsteht, wenn in einem Bild Farben mit starker Sättigung nebeneinander liegen. Diese leuchten auf der Netzhaut nach und führen zu visuellen Überlagerungen.)

Dunkles Thema, was tun und was nicht

Der Einsatz von Schatten, um Tiefe zu erzeugen und ein Element nach vorn zu bringen, ist auf dunklen Hintergründen wenig wirksam. Statt dessen möchten Sie vielleicht eher die Hintergrundfarbe des Elements heller machen.

Material design liefert gute Leitlinien, um Designs für dunkle Themen zu entwerfen.

Dunkle Themen kommen nicht nur den Wünschen der Benutzer*innen besser entgegen. Sie können auf AMOLED Bildschirmen auch deutlich Energie sparen. Solche Panels finden sich zunehmend in Mobilgeräten und in Desktop-Monitoren.

Vergleich des Stromverbrauchs bei Light und Dark Theme

Eine Studie von 2018 bei Android-Geräten zeigte Energieeinsparungen von bis zu 60%, abhängig von der Bildschirmhelligkeit und der allgemeinen Benutzeroberfläche. Die 60% wurden durch den Vergleich von hellem und dunklem Thema in einem pausierten Youtube-Wiedergabebildschirm ermittelt, wobei das Gerät auf 100% Bildschirmhelligkeit eingestellt war.

Sie sollten, wann immer möglich, für Ihre Besucher*innen ein dunkles Thema bereitstellen.

Responsiv zum Container

Eine der spannendsten Entwicklungen in CSS sind Containerabfragen, häufig auch Elementabfragen genannt. Man kann die Auswirkungen eines Übergangs von seitenbasierender zu containerbasierender Responsivität nicht hoch genug einschätzen.

Hier ist ein Beispiel für die Leistungsfähigkeit von Containerabfragen. In Abhängigkeit vom Elterncontainer können Sie jeden Style der Kartenelemente manipulieren, darunter auch die Sichtbarkeit der Linkliste, die Schriftgrößen und das grundsätzliche Kartenlayout.

Demo in Codepen – Containerabfragen können ab Google Chrome 91 in chrome://flags aktiviert werden

Das Beispiel zeigt zwei identische Komponenten mit unterschiedlichen Containergrößen. Die Container befinden sich in einem CSS-Grid, dessen Spaltenbreite mit JavaScript verändert wird. Jede Komponente füllt den ihr zugewiesenen Platz aus und passt ihren Style entsprechend an.

Diese Flexibilität ist allein durch Medienabfragen nicht herstellbar.

Containerabfragen ermöglichen ein viel dynamischeres Vorgehen bei responsivem Design. Ganz gleich, ob Sie eine solche Kartenkompontente in eine Sidebar legen, als Hero-Abschnitt verwenden oder in eine Zelle eines Grids stecken, die Komponente enthält die erforderlichen Informationen für Responsivität und passt ihre Darstellung abhängig von ihrem Container an, und nicht abhängig vom Viewport.

Dafür ist die @container-@-Regel erforderlich. Sie funktioniert ähnlich wie eine @media-Abfrage, aber statt auf den Viewport beziehen sich die Abfragen auf den Container, in dem sich ein Element befindet.

.card {
  container-type: size;
}

.time {
  font-size: 1.5rem;
}

@container (max-width: 50em) {
  .links {
    display: none;
  }

  .time {
    font-size: 1.25rem;
  }

  /* ... */
}

Zunächst wird für Elemente mit der Klasse card festgelegt, dass sie einen Container darstellen. Seit Uma Kravets ihren Artikel schrieb, hat sich an der Spezifikation einiges geändert, der Stand 2023 ist, dass die CSS Eigenschaft container-type verwendet wird, um einen Query-Container zu erzeugen. Der Containertyp kann inline-size sein, wenn es nur um die Größe in Inline-Richtung geht (also die Breite bei europäischer Schreibrichtung) oder size, wenn man die Größe sowohl in Inline- wie auch in Blockrichtung abfragen möchte. Weitere Querycontainertypen wurden aus der Spezifikation gestrichen.

Die @container Regel ermöglicht nun die Abfrage von Medienfeatures für das Element, zu dem dieser Containerkontext gehört. Das gezeigte Beispiel würde also in einem Containerkontext mit einer maximalen Breite von 50em die Links ausblenden und die Anzeige der Zeit verkleinern.

Karten mit Containerabfragen

In dieser Demo-Webseite über Pflanzen sind alle Produktkarten – im Hero-Bereich, im Produkte-Grid und in der „Zuletzt angesehen“-Sidebar – exakt die gleiche Komponente, mit exakt dem gleichen Markup.

Demo in Codepen – Containerabfragen können ab Google Chrome 91 in chrome://flags aktiviert werden

Das gesamte Layout verwendet keine @media-Abfragen, nur @container-Abfragen. Das ermöglicht es jeder einzelnen Produktkarte, ihren Platz mit dem passenden Layout auszufüllen. Das Grid verwendet beispielsweise ein minmax-Spaltenlayout, um die Elemente an ihren Platz fließen zu lassen, und das Grid umzulayouten wenn der Platz zu sehr komprimiert wird (was bedeutet, dass es die minimale Größe erreicht hat).

Ein Hinweis: Selfhtml empfiehlt den Einsatz von em-Maßen statt px-Maßen. Una Kravets hat das für ihre Beispiele nicht gemacht. Um den hier dargestellten Code in ihren Codepens besser wiederfinden zu können, wurde die px-Angabe im Blog beibehalten.

.product {
  contain: layout inline-size;
}

@container (min-width: 350px) {
  .product-container {
    padding: 0.5rem 0 0;
    display: flex;
  }

  .product-container button {
    /* ... */
  }
}
<div class="product">              <!-- Grid-Zelle als @container -->
  <div class="product-container">  <!-- Die eigentliche Pflanzenkarte -->
    <figure><img src="..." />
    </figure>
    <div>
      <h3>Succulent</h3>
      <span class="price">$8.99</span>
      <p>This plant is a very good one.</p>
      <button>Add to Cart</button>
    </div>
  </div>
</div>

Wenn im Grid mindestens 350px Platz sind, wird das Kartenlayout horizontal. Das geschieht mittels display:flex, das defaultmäßig eine flex-direction von row hat.

Wenn weniger Platz ist, stapeln sich die Bereiche der Produktkarte übereinander. Jede Produktkarte stylt sich selbst, das ist etwas, das allein mit globalen Stilen nicht umsetzbar wäre.

Mischen von Container- und Medienabfragen

Ein weiteres interessantes Einsatzgebiet für Containerabfragen ist eine Kalenderkomponente. Damit können Sie Kalendereinträge und andere Abschnitte basierend auf der verfügbaren Breite layouten.

Demo in Codepen – Containerabfragen können ab Google Chrome 91 in chrome://flags aktiviert werden

Diese Demo nutzt Containerabfragen, um Layout und Style für den Tag und Wochentag anzupassen. Ebenso werden Ränder und Schriftgröße für die Kalendereinträge modifiziert, so dass der Platz besser genutzt wird.

Wird der Viewport zu schmal, wird mit einer Medienabfrage das ganze Layout umgebaut. Dieses Beispiel zeigt, was man durch eine Kombination von Medienabfragen und Containerabfragen erreichen kann. Mit den Medienabfragen steuert man die globale Sicht, oder Makrostyles, und die Containerabfragen übernehmen die lokale Sicht der Containerelemente, die Mikrostyles.

Wir können also nun in einer UI Komponente zwischen Makro- und Mikrolayout unterscheiden, um sauber abgestufte Designentscheidungen treffen zu können.

Containerabfragen heute verwenden

Diese Code-Demonstrationen sind verwendbar, wenn Sie Chrome 91 oder neuer verwenden und im chrome:flags Bereich #enable-container-queries einschalten. Una Kravets schrieb noch, dass man eine Canary-Version von Chrome brauche – mit Chrome-Version 91.0.4472.114 ist das nicht mehr der Fall. Mit dem Flag wird die Unterstützung von @container und die Werte inline-size und block-size der contain Eigenschaft freigeschaltet. Darüber hinaus wird das Grid-Displaymodul auf die LayoutNG Engine umgeschaltet. Aber tun Sie das nur temporär. Die Engine ist in diesem Bereich noch nicht stabil, sie kann Chrome zum Absturz bringen.

Scoped Styles

Um Containerabfragen sinnvoll nutzen zu können, diskutiert die CSS-Arbeitsgruppe (CSSWG) über scoped styles (Geltungsbereiche für Styles). Sie möchten erreichen, dass Namespaces gebildet werden können, so dass man Kollisionen von Komponenten vermeiden kann.

Es geht dabei nicht um das scoped-Attribut des <style>-Elements, sondern um die @scope-Regel, die allerdings in derzeitigen Specs und Working Drafts zurückgestellt ist.

Scoped Styles

Das Bild wurde ursprünglich von Miriam Suzanne gestaltet, die auch den entsprechenden Vorschlag bei der CSS WG eingebracht hat.

Die @scope-Idee von Miriam Suzanne würde so etwas wie einen Donut-förmigen Geltungsbereich von CSS-Regeln ermöglichen. Stellen Sie sich ein Tab-Control vor. Für das eigentlich Tab-Control möchten Sie spezielle CSS-Regeln formulieren. Diese sollen aber nicht außerhalb des Controls gelten, und für den Inhalt der Tab-Panels sollen sie auch nicht gelten, um dort nicht zu stören.

<div class="tabs">
   <ul class="tab-header"><li></li><li></li><li></li></ul>
   <div id="panel_1" class="panel">...</div>
   <div id="panel_2" class="panel">...</div>
   <div id="panel_3" class="panel">...</div>
</div>

Angenommen, Sie möchten Styles definieren, die für das tabs div und seine Kind-Elemente gelten. Zum Beispiel, um die tab-header Liste passend zu formatieren. Das können Sie auch jetzt schon tun, aber dann muss der Seitenautor beim Gestalten der Panels gut aufpassen, dass nicht irgendwelche Regeln für das Tab-Control in seine Panels hinein wirken.

Miriam Suzanne schlägt vor, das so zu lösen:

@scope (.tabs) to (.panel) {
  .tab-header {
    display: flex;
  }

  .light-theme :scope .tab-header tab {
    background-color: dark-blue;
  }
}

Auf den Panels kann nun eine Klasse tab-header genutzt werden, ohne mit den tab-Headern des Tab-Control zu kollidieren. Die zweite Regel deutet an, wie man auf Klassen reagieren kann, die außerhalb des Scopes gesetzt sind. Hierfür wird die schon existierende :scope Pseudoklasse genutzt.

Es ist allerdings nicht damit zu rechnen, dass diese @-Regel in der nächsten Zeit implementiert wird.

Responsiv zum Formfaktor

Ein weiteres Thema in diesem Artikel ist die Zunahme von Formfaktoren und die zunehmenden Möglichkeiten, die wir als Web-Community benötigen, um dafür Designs zu entwerfen.

Das Diagramm stammt von Microsoft Edge Explainers

Faltbare (oder flexible) Bildschirme und Design für bildschirmübergreifende Darstellung (screen spanning) sind Beispiele für neue Formfaktoren. Screen spanning ist übrigens eine weitere Spec, an der gearbeitet wird, um diese neuen Anforderungen bedienen zu können.

Eine experimentelle Medienabfrage für screen-spanning könnte uns hier weiterhelfen. Zur Zeit verhält sie sich wie folgt: @media (spanning: <faltrichtung>). Das Demovideo zeigt ein Grid-Layout mit zwei Spalten. Eine hat die Breite --sidebar-width, die auf einen Defaultwert von 5rem gesetzt wird. Die andere ist 1fr. Wenn das Layout auf einem Faltbildschirm mit einer einzelnen vertikalen Falte dargestellt wird, wird der Wert von --sidebar-width mit dem Umgebungswert für die Breite des linken Teils ersetzt. env(fold-left) finden Sie zur Zeit noch in keinem Browser.

:root {
  --sidebar-width: 5rem;
}

@media (spanning: single-fold-vertical) {
  --sidebar-width: env(fold-left);
}

main {
    display: grid;
    grid-template-columns: var(--sidebar-width) 1fr;
}

Das ermöglicht ein Layout, in dem die Sidebar – in diesem Fall die Navigation – eine der Faltseiten ausfüllt und das UI der Anwendung die andere. Das vermeidet einen „Spalt“ im UI.

Die Chrome Entwicklerwerkzeuge enthalten einen Emulator für Faltbildschirme, um bei Debuggen zu helfen und Prototyp-Code für screen spanning im Browser zu ermöglichen.

Fazit

UI-Design, das über rechteckige, flache Bildschirme hinausgeht, ist ein weiterer Grund, weshalb Containerabfragen und scoped styles so wichtig sind. Sie geben Ihnen die Gelegenheit, Komponenten-Styles vom Seitenlayout und globalen Styles zu isolieren, und so ein robusteres responsives Design zu ermöglichen.

Das bedeutet, dass Sie nun ein Makro-Layout mit seitenbasierenden @media-Abfragen entwerfen können, und dabei auch screen spanning berücksichtigen können. Das Mikrolayout von Komponenten können Sie dagegen mit Containerabfragen in ihr Umfeld einpassen.

Mit Medienfeatures für Benutzereinstellungen können Sie all das dann an die besonderen Anforderungen Ihrer Besucher*innen anpassen.

Das ist die neue Responsivität.

Sie kombiniert Makro- und Mikrolayout mit Benutzereinstellungen und Formfaktoren.

Jede dieser Veränderungen würde schon für sich betrachtet die Art, wie wir für das Web designen, verändern. Aber zusammengenommen bedeuten sie bereits für das Konzipieren eines responsiven Designs eine wirklich große Verschiebung. Es ist an der Zeit, responsives Design über die Viewportgröße hinaus zu denken und diese neuen Maßstäbe einzubeziehen.

Die nächste Ära responsiven Designs ist hier, und Sie können bereits damit anfangen, sie zu erforschen.

web.dev/learnCSS #

Wenn Sie Ihr CSS Spiel auf einen neuen Level bringen wollen und vielleicht auch ein paar Grundlagen noch einmal durchgehen möchten, startet Una Kravets' Team auf web.dev einen neuen, völlig kostenlosen CSS Kurs mit Referenz. Sie finden ihn über web.dev/learnCSS.