Entwurf: Die Neue Responsivität - Update
Vor gut einem Jahr haben wir einen Artikel von Una Kravets übersetzt und präsentiert, der sich unter anderem mit Container Queries beschäftigte.
Seit ein paar Wochen werden Container Queries von Chromium-Browsern auch ohne explizite Freischaltung unterstützt, und die Spec-Verfasser Tab Atkins, Florian Rivoal und Miriam E. Suzanne haben fleißig an der Spezifikation geschraubt.
Container-Abfragen sind ein Meilenstein im Web-Layout. Ohne sie ist es extrem schwierig, das Layout eines Webseiten-Elements basierend auf seiner eigenen Größe zu gestalten - CSS bietet einfach keine Werkzeuge dafür.
Sicher, man kann mit JavaScript auf das resize-Event reagieren oder einen ResizeObserver auf das betreffende Element legen, und dann je nach gewünschtem Layout mit Klassen, Custom Properties oder style-Attributen eingreifen. Es ist aber umständlich, und JavaScript ist eigentlich nicht zum Layouten da.
Eine Container-Abfrage sieht beispielsweise wie folgt aus:
@container (min-width: 40em) {
article p {
column-count: 2;
}
header nav ul {
display: flex;
}
}
Man muss solche Abfragen teilweise von innen nach außen lesen. Sie bestehen zunächst einmal aus ganz normalen CSS Regeln. Die Selektoren dieser Regeln ermitteln eine bestimmte Menge an Elementen, und jetzt erst wird geschaut, ob sich diese Elemente in einem Größencontainer befinden.
Es könnte also sein, dass der article p
Selektor 17 p Elemente in 3 Artikeln findet. Der Browser prüft nun für jedes p-Element einzeln, ob er einen Size-Container hat und ob dieser mindestens 40em breit ist. Und nur dann wird die CSS Regel angewendet.
Und woher weiß der Browser nun, was der Container ist?
Die Version der Spezifikation, auf der der vorjährige Artikel von Uma Kravets basierte, verwendete noch die contain
-Eigenschaft, um einen solchen Container festzulegen und so stand es auch letztes Jahr im Selfblog. Dies hat sich in der Spezifikation vom August 2022 geändert, es gibt jetzt eine eigenes Eigenschaft container-type:
<main>
<article>
<h2>Container Queries</h2>
<p>Bla Bla Bla ... </p>
</article>
</main>
Um nun festzulegen, dass die Artikel der Size-Container für ihren Inhalt sein sollen, schreiben wir ins CSS:
article {
containment-type: inline-size;
}
und schon wird der Paragraph zweispaltig, wenn der Artikel mindetens 40em breit ist.
Das ist natürlich nichts Besonderes und ließe sich mit einer normalen @media-Query genauso abhandeln. Aber es gibt selbst bei diesem HTML schon Gemeinheiten zu beachten.
- Es könnte noch einen nav-Bereich geben, links von den Artikeln. Dessen Breite müsste man für diese @media-Query berücksichtigen
- Die Navigation könnte eine Breite haben, die von der Textlänge der einzelnen Navigationspunkte abhängt
- Die Navigation könnte einblendbar sein, und zwar so, dass sie den Inhalt schmaler macht
Und mit @media-Queries ist es völlig vorbei, wenn der main-Bereich ein Grid oder eine Flexbox ist, um mehrere Artikel nebeneinander darstellen zu können.
Der Containment-Typ inline-size
erlaubt nur Abfragen auf die Containerbreite. Es gibt einen anderen Typ, size
, der auch das Abfragen der Höhe ermöglicht. Aber das ist mit Vorsicht zu genießen!
Es war schon im CSS Containment Level 2 Modul so, dass sich mittels contain:size
festlegen ließ, dass eine Box ohne Beachtung ihres Inhalts layoutet werden kann. Das hat Performance-Vorteile, setzt aber eben auch voraus, dass die Größe der Box ohne Beachtung ihres Inhalts bestimmbar ist. Und auch dort galt schon: der Default für nicht bestimmbare Breiten- oder Höhenangaben ist 0.
Das CSS Containment Level 3 Modul, das die Container-Abfragen hinzufügt, erweitert auch die contain
-Eigenschaft um den Wert inline-size
. Die Höhe der Box kann auf diese Weise immer noch von ihrem Inhalt abhängig sein, aber die Breite wird unabhängig vom Inhalt festgelegt.
Die gleichen Gründe führen dazu, dass eine containment-type Angabe von inline-size oder size dazu führt, dass der Inhalt des Containers nicht mehr für die Bestimmung der Boxbreite oder sogar der gesamten Boxgröße herangezogen wird.
Codebeispiele, die für Version 92 von Chromium gemacht wurden und sich auf die contain-Eigenschaft beziehen, um Container-Queries durchzuführen, funktionieren nicht mehr. Gemäß der Angaben bei caniuse.com wurde schon in Chrome 93 auf die neue Spec umgestellt, auch wenn diese Version längere Zeit noch im Draft-Modus war.
(todo: Beispiel im Selfwiki machen)
Rolf
sumpsi - posui - obstruxi