11. Okt 2021
Lesedauer 12 Min.
Container Queries
Komponentenbasiertes Layouten
Container Queries basieren auf CSS-Containment und ermöglichen unterschiedliche Styles je nachdem, wo Elemente stehen.

Eine der wichtigsten Komponenten für anpassungsfähige, responsive Webseiten sind die Media Queries. Damit fragen Sie die Größe des Viewports ab und können dann in Abhängigkeit davon unterschiedliche Formatierungen anwenden. Allerdings orientieren sich Media Queries immer am Viewport. Das genügt bei einfachen Layouts, jedoch nicht bei einem Komponenten-basierten Ansatz. Im Artikel lesen Sie, welche Lösungen es in Zukunft dafür geben wird und wie man sich bis dahin behilft. Außerdem erfahren Sie, warum und wie Sie heute schon contain für eine schnellere Browserdarstellung nutzen können.
Die Grenzen von Media Queries
Gehen wir von einer einfachen Komponente aus, die aus einem Bild und Text besteht. Um die Komponente herum befindet sich ein .wrapper-Element:
<div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"wrapper"</span>>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">article</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>></span></span>
<span class="xml"> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"image"</span>></span></span>
<span class="xml"> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"bild.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"bild"</span>></span></span>
<span class="xml"> <span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
<span class="xml"> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"content"</span>></span></span>
<span class="xml"> <span class="hljs-tag"><<span class="hljs-name">p</span>></span>Lorem ipsum dolor <span class="hljs-tag"></<span class="hljs-name">p</span>></span></span>
<span class="xml"> <span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
<span class="xml"> <span class="hljs-tag"></<span class="hljs-name">article</span>></span></span>
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
Bei genügend Platz sollen Bild und Text nebeneinander dargestellt werden, andernfalls untereinander (Bild 1).

Zwei Darstellungsvariantender Komponente: Bild und Text untereinander oder nebeneinander(Bild 1)
Maurice
Wenn man die Komponente isoliert betrachtet, lassen sich entsprechende Media Queries formulieren. Mit Gridlayout funktioniert das beispielsweise so:
<span class="hljs-selector-class">.card</span> {
<span class="hljs-attribute">display</span>: grid;
<span class="hljs-attribute">grid-template-areas</span>: <span class="hljs-string">"image"</span> <span class="hljs-string">"content"</span>;
}
@<span class="hljs-keyword">media</span> (min-width: <span class="hljs-number">700px</span>) {
<span class="hljs-selector-class">.card</span> {
<span class="hljs-attribute">grid-template-areas</span>: <span class="hljs-string">"image content"</span>;
<span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-number">1</span>fr <span class="hljs-number">1</span>fr;
}
}
<span class="hljs-selector-class">.card</span> <span class="hljs-selector-class">.image</span> {
<span class="hljs-attribute">grid-area</span>: image;
}
<span class="hljs-selector-class">.card</span> <span class="hljs-selector-class">.content</span> {
<span class="hljs-attribute">grid-area</span>: content;
}
Am Anfang wird eine einspaltige Darstellung definiert. Die Anzahl an Strings hinter grid-template-areas definiert die Anzahl an Zeilen, hier sind es zwei Strings, das heißt, es sind zwei Zeilen. Das ändert sich innerhalb der Media Query. Ab einer Viewportbreite von 400px ist die Darstellung zweispaltig, hinter grid-template-areas steht jetzt nur ein String mit zwei Wörtern, was zwei Spalten bedeutet. Außerdem ist die Breite der Spalten mit grid-template-columns festgelegt. Schließlich werden die Elemente den Bereichen mit grid-area zugewiesen. So weit, so gut.In der Realität steht eine solche Bild-/Textkomponente aber nicht allein im Layout, sondern sie befindet sich in unterschiedlichen Bereichen. Damit genügt es nicht mehr, den Viewport über Media Queries abzufragen (Bild 2). Die optimale Darstellung hängt nämlich davon ab, wo die Komponente steht: Wenn sich die Bild-/Textkomponente in einem schmalen Seitenbereich befindet, soll ebenfalls die Darstellung untereinander gewählt werden – es spielt dabei hingegen keine Rolle, wie groß der Viewport insgesamt ist. Genau in solchen Fällen brauchen wir statt Media Queries, die auf den Viewport reagieren, Container Queries, die den verfügbaren Platz des Containers abfragen, in dem sich die Komponente befindet. Eine solche Neuerung wurde schon lange in der CSS-Entwicklergemeinschaft diskutiert. Jetzt endlich gibt es einen ersten Entwurf, der auch bereits im Chrome hinter einem Flag funktioniert.

Wenn die Anordnungnur vom Viewport abhängt, kommt es zu solchen unerwünschten Darstellungen: Obwohl rechts zu wenig Platz ist, werden Bild und Text nebeneinander dargestellt(Bild 2)
Maurice
Eine der Herausforderungen bei Container Queries ist die Gefahr von Zirkeln. Zu solchen kommt es, wenn die Darstellung eines Elements vom Container abhängt, aber die Darstellung des Containers selbst sich wiederum durch die Elemente, die drinnen stehen, ändert. Ein wichtiger Schritt, um solche Probleme zu verhindern, ist die Nutzung von CSS-Containment.
CSS-Containment
Im Unterschied zu den Container Queries, die gerade erst in der Entwicklung sind, ist das CSS Containment-Module Level 1 seit Dezember 2020 eine W3C-Recommendation und hat auch eine solide Browserunterstützung. Im Herbst 2021 funktioniert es in allen aktuellen Browsern außer Safari (Bild 3).
Browserunterstützungfür die contain-Eigenschaft(Bild 3)
Maurice
CSS-Containment ist relevant für Webseiten, bei denen nach dem Ladevorgang weitere Inhalte beispielsweise mit JavaScript nachgeladen werden. Hier können Sie dank CSS-Containment für eine schnellere Darstellung durch den Browser sorgen. Für rein statische Seiten, die keine Inhalte nachladen, ist diese Technik nicht relevant. Damit Browser eine Webseite effizient rendern können, müssen sie wissen, welche Teile der Webseite den aktuellen Teil beeinflussen oder ob der gerade darzustellende Bereich unabhängig von anderen Inhalten ist. Browser haben heuristische Techniken, um das zu ermitteln – dank CSS-Containment können Sie den Browsern aber dabei helfen.Sie können CSS-Containment heute schon einsetzen: Ein Browser wie Safari, der die Angaben nicht interpretiert, wendet die Performance-Verbesserung zwar nicht an, die anderen Browser profitieren aber trotzdem. Allerdings hat contain bestimmte Nebeneffekte – und wenn Sie auf diese setzen, müssen Sie sie in nicht unterstützenden Browsern nachbessern. Dazu gleich mehr. Das CSS-Containment-Modul Level 1 definiert eine Eigenschaft contain. So können Sie sie beispielsweise anwenden:
<span class="hljs-selector-class">.item</span> {
<span class="hljs-attribute">contain</span>: content;
}
Die Eigenschaft contain erlaubt einen von mehreren Werten:Das sind die grundlegenden Werte, wobei auch mehrere gleichzeitig eingesetzt werden können, Sie können beispielsweise contain: layout paint schreiben. Außerdem gibt es zwei Abkürzungen: Bei strict werden alle Arten von Containment benutzt und bei content werden alle Formen von Containment bis auf size angewandt. contain empfiehlt sich beispielsweise, wenn es einen Bereich auf der Webseite mit Nachrichten gibt, die nachgeladen werden. Wenn keine dieser Nachrichten den Rest der Webseite beeinflusst, dann ist contain: content für den Nachrichtenbereich sinnvoll. Falls man die Größe der Nachrichten kennt, könnte man contain: strict für einen noch besseren Effekt nutzen.
Nebenwirkungen von contain
Die contain-Angaben haben allerdings auch mehrere Nebenwirkungen, die zu beachten sind. contain: layout erstellt einen neuen Formatierungskontext (formatting context). Das heißt, dass es bei Positionierungen für Kindelemente den Referenzpunkt bildet, so als wäre position: relative definiert. Ein kleines Beispiel verdeutlicht das:
<div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"container"</span>>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"image"</span>></span><span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"…"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">" "</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
Zu diesem Bespielcode gibt es die beiden folgende CSS-Formatierungen
<span class="hljs-selector-class">.container</span> {
<span class="hljs-attribute">contain</span>: layout;
}
<span class="hljs-selector-class">.image</span> {
<span class="hljs-attribute">position</span>: absolute;
<span class="hljs-attribute">bottom</span>: <span class="hljs-number">0</span>;
}
Hier ist der Bezugspunkt für die absolute Positionierung von .image das umfassende .container-Element – weil contain: layout angegeben ist. Das heißt, wenn Sie contain: layout nutzen und zugleich bei Kindelementen position: absolute angeben, müssen Sie für nichtunterstützende Browser für .container die Regel position: relative ergänzen:
<span class="hljs-selector-class">.container</span> {
<span class="hljs-attribute">contain</span>: layout;
<span class="hljs-attribute">position</span>: relative;
}
contain: paint hat noch eine weitere Nebenwirkung, die zum Beispiel auftritt, wenn ein Kindelement gefloatet ist. Dieses Mal wird folgender CSS-Code auf .container und .image angewendet:
<span class="hljs-selector-class">.container</span> {
<span class="hljs-attribute">contain</span>: paint;
}
<span class="hljs-selector-class">.image</span> {
<span class="hljs-attribute">float</span>: left;
}
Dann wird das gefloatete Element umschlossen – so als würden Sie display: flow-root beim .container anwenden. Das heißt, wenn Sie auf diesen Nebeneffekt setzen, sollten Sie zusätzlich display: flow-root ergänzen:
<span class="hljs-selector-class">.container</span> {
<span class="hljs-attribute">contain</span>: paint;
<span class="hljs-attribute">display</span>: flow-root;
}
contain: size hat die heftigsten Nebenwirkungen: Wenn Sie es bei einem Element nutzen, ohne dass Sie explizite Ausmaße definiert haben, verhalten sich die folgenden Elemente so, als hätte das Element eine Höhe von 0px. Das W3C zeigt das an folgendem Beispiel:
<span class="hljs-selector-tag">img</span> {
<span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
<span class="hljs-attribute">aspect-ratio</span>: <span class="hljs-number">1</span>/<span class="hljs-number">1</span>;
<span class="hljs-attribute">contain</span>: size;
}
Diese Angaben werden auf ein Bild angewendet. Die Codierung dafür sieht so aus:
<<span class="hljs-selector-tag">img</span> src=<span class="hljs-string">"bild-300x100.jpg"</span> alt=<span class="hljs-string">"bild"</span>>
Ohne aspect-ratio würde die Höhe als 0 behandelt – und die nachfolgenden Elemente würden dieses Element verdecken. Im Beispiel ist das Bild nur deshalb zu sehen, weil durch width in Kombination mit aspect-ratio die Ausmaße exakt definiert sind.Das W3C spricht in der Spezifikation für Entwickler die Empfehlung aus, contain: content anzuwenden. Zwar würde contain: strict hinsichtlich der Performance noch mehr bringen, das geht aber nur, wenn die Ausmaße der Elemente bekannt sind. Außerdem sollten Sie die Nebenwirkungen bedenken – und bei Bedarf für nicht-unterstützende Browser wie Safari Angaben wie position: relative oder display: flow-root ergänzen.
Container Queries
Kommen wir nun zu den Container Queries. Eine erste Implementierung der Container-Queries findet sich in Chrome. Um die Container Queries zu testen, müssen Sie diese in Chrome aktivieren. Geben Sie chrome://flags/ in die Adresszeile ein und suchen Sie nach Container. Dann wählen Sie Enable CSS Container Queries.Noch mal zurück zur contain-Eigenschaft: Dort gibt es den Wert size, wenn das Element eine bekannte Größe (Höhe + Breite) hat. Für Container Queries wird diese Angabe erweitert, so dass man unterscheiden kann, ob die Ausmaße in der Inline-Achse (bei Schreibung von links nach rechts die Breite) oder in der Block-Achse (bei Schreibung von links nach rechts die Höhe) bekannt sind.Nehmen wir unsere Text-/Bildkomponente aus den beiden ersten Listings. Dieses Mal soll die Darstellung nicht vom Viewport abhängen, sondern von dem Bereich, in dem sich die Komponente befindet. Diesen Bereich müssen wir zum Container machen und ihm contain spendieren. Im Beispiel nehmen wir dafür das umfassende .wrapper-Element:
<span class="hljs-selector-class">.wrapper</span> {
<span class="hljs-attribute">contain</span>: layout style inline-size;
}
Übrigens werden Sie in manchen Tutorials die Angabe contain: layout inline-size finden. Das funktioniert im September 2021 im Chrome nicht mehr, es klappt hingegen, wenn Sie style ergänzen wie im Beispiel oben. Daran erkennt man allerdings, dass es sich bei der Syntax erst um einen Entwurf handelt und noch Änderungen zu erwarten sind. Statt contain können Sie auch die container-Eigenschaft wie folgt nutzen:
<span class="hljs-selector-class">.wrapper</span> {
<span class="hljs-attribute">container</span>: inline-size;
}
Durch die contain/container-Ergänzung erstellen Sie einen Containment-Kontext. Auf diesen können Sie sich dann in einer @container-Query beziehen, die Sie anstelle der Media Query einsetzen:
@<span class="hljs-keyword">container</span> (min-width: <span class="hljs-number">400px</span>) {
<span class="hljs-selector-class">.card</span> {
<span class="hljs-attribute">grid-template-areas</span>: <span class="hljs-string">"image content"</span>;
<span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-number">1</span>fr <span class="hljs-number">1</span>fr;
}
}
Das heißt, um aus einer Media Query eine Container Query zu machen, sind zwei Schritte notwendig: Die umfassenden Elemente müssen über die contain/container-Eigenschaft zu Container gemacht werden. Im Beispiel ist es das .wrapper-Element; es würde nicht funktionieren, wenn man diese Angabe bei .card macht – denn das ist ja das Element, das sich unterschiedlich verhalten soll. Außerdem brauchen Sie dann die @container-Query, die aufgebaut ist wie eine @media-Query. Hier müssen Sie außerdem den Wert (min-width etc.) anpassen. In den Browsertools von Chrome finden sich bereits nützliche Hinweise zur Arbeit mit Container-Queries (Bild 4). Das Element, das als Containment-Kontext dient, hat die Markierung container. In unserem Beispiel ist das .wrapper. Bei dem Element, für das die @container-Query Anpassungen definiert, sehen Sie auch die @container-Query aufgeführt – im Beispiel also bei .card. Oberhalb dieser @container-Query steht nach einem Pfeil das Element, auf das die Query sich bezieht: Wenn man darüber hovert zeigt sich das Feature, auf das es reagiert, im Beispiel inline-size samt aktueller Größe.

Markierungvon containment-Kontexten in den Chrome-Dev-Tools(Bild 5)
Maurice
Inzwischen widmet sich ein W3C-Entwurf den Container Queries. Hierzu ein Beispiel aus:
<span class="hljs-selector-tag">main</span>, <span class="hljs-selector-tag">aside</span> {
<span class="hljs-attribute">container</span>: inline-size;
}
<span class="hljs-selector-class">.media-object</span> {
<span class="hljs-attribute">display</span>: grid;
<span class="hljs-attribute">grid-template</span>: <span class="hljs-string">'img'</span> auto <span class="hljs-string">'content'</span> auto / <span class="hljs-number">100%</span>;
}
@<span class="hljs-keyword">container</span> (inline-size > <span class="hljs-number">45em</span>) {
<span class="hljs-selector-class">.media-object</span> {
<span class="hljs-attribute">grid-template</span>: <span class="hljs-string">'img content'</span> auto / auto <span class="hljs-number">1</span>fr;
}
}
main, aside werden zu Containern über die container-Eigenschaft und den Wert inline-size. In der @container-Abfrage wird geprüft, ob die Breite (inline-size) größer als 45em ist. Das größer-als- oder kleiner-als-Zeichen anstelle von min-/max- ist übrigens bei Media Queries Level 4 vorgesehen, funktioniert momentan aber erst im Firefox. Wenn Sie das Beispiel im Chrome mit aktiviertem Flag zum Laufen bringen wollen, müssen Sie die @container-Regel so umformulieren:
<span class="hljs-variable">@container</span> (<span class="hljs-attribute">min-width</span>: <span class="hljs-number">45em</span>) { ...}
Im Entwurf finden sich auch viele weitergehende Techniken. Erst einmal ist die Eigenschaft container eigentlich eine verkürzte Schreibweise für container-type und container-name. container: inline-size steht eigentlich für:
container-<span class="hljs-keyword">type</span>: inline-<span class="hljs-built_in">size</span>;
Container-<span class="hljs-keyword">name</span>: <span class="hljs-keyword">none</span>;
Im Beispiel wurde container: inline-size benutzt, das heißt, bei der Query werden die Ausmaße des Containers berücksichtigt. Das ist sicher das Container-Feature, das man am häufigsten brauchen wird. Aber es sind weitere in Planung, wie etwa aspect-ratio, um das Seitenverhältnis eines Bereichs abzufragen, oder auch orientation mit den Werten landscape und portrait. Neben Abfragen, die sich auf die Ausmaße von Elementen beziehen, sind auch Style Container Features im Gespräch, um die (berechnete) Formatierung eines Containers abzufragen. Dann kann man in Abhängigkeit des aktuellen Wertes einer Eigenschaft mehrere andere Formatierungen ändern – ebenfalls eine nützliche Sache.Zudem soll man mit State Container Features auf Zustände reagieren können: darauf, ob ein Element sichtbar ist, ob ein mit position: sticky versehener Container in seiner normalen Flow-Position ist oder Ähnlich. Die zweite Eigenschaft ist container-name. Benannte Container können bei verschachtelten Containern sinnvoll sein: Dadurch können Sie festlegen, dass sich eine Komponente nicht auf den Container beziehen soll, der sich in der Hierarchie direkt darüber befindet, sondern auf einen noch höheren.
Höhe oder Breite des Viewports
Sie kennen sicher die Viewport-Einheiten vh, vw, um die Höhe oder Breite des Viewports abzufragen. Parallel dazu sind Container-Units qw und qh für die Container-Ausmaße geplant. Diese neuen Einheiten können Sie ebenfalls schon in Chrome bei aktiviertem Flag ausprobieren. Eine Schriftgröße rein von der Container-Größe abhängig zu machen, wäre nicht sinnvoll. Aber Sie könnten die Schriftgröße je nach Platz im Container leicht größer oder kleiner machen (Bild 5), indem Sie calc() nutzen:
font-<span class="hljs-built_in">size</span>: calc(<span class="hljs-number">1</span><span class="hljs-built_in">rem</span> + <span class="hljs-number">1</span>qw);
Sinnvoll sind diese neuen Einheiten nicht zuletzt für padding oder margin – wo sich Prozentwerte ja immer auf das Element selbst und nicht das umgebende beziehen, und deswegen keine Alternative sind.

Mit Container-Unitswird die Überschrift größer oder kleiner je nach Breite des Containers(Bild 6)
Maurice
Die Spezifikation bietet also wesentlich mehr, als man zunächst erwarten würde. Was natürlich sehr sinnvoll ist: Wenn schon so etwas umwälzend Neues wie Container Queries eingeführt werden, dann sollten die Container Queries auch möglichst alles abdecken, was damit im Zusammenhang steht. Dabei wird klar, dass die eigentliche Herausforderung bei solchen Neuerungen nicht in der Implementierung liegt, sondern in der exakten Definition dessen, was wann wie geschehen soll.Besonders Zirkelschlüsse müssen vermieden werden. Problematisch ist vor allem, dass in manchen Situationen der Inhalt eines Containers dessen Ausmaße beeinflusst. Beispielsweise können bei mehr Inhalt Scrollbalken erscheinen und bewirken, dass ein Element mit einer Breitenangabe in Prozent schmaler wird.Was macht man aber, solange die Container Queries noch nicht weiter gediehen sind? Hier stehen mehrere Strategien zur Auswahl. Sie können unterschiedliche Klassen zuweisen, je nachdem, wo die Komponente steht, und darüber Anpassungen durchführen.
Alternativen zu nativen Container-Queries
Die Schwierigkeit bei diesem Ansatz ist, dass Sie immer genau wissen müssen, was wo stehen kann und wie dann die optimale Darstellung ist. In CSS existieren heute schon mehrere Techniken, mit denen Sie Anpassungen ohne Media Queries durchführen können, zum Beispiel Gridlayout oder Flexbox. Das sehen wir uns gleich noch näher an. Die dritte Möglichkeit besteht darin, mit JavaScript nachzubessern. Dafür gibt es beispielsweise Bibliotheken wie EQCSS.Mit CSS Grid können Sie ein Raster definieren, bei dem ein Umbruch in der Darstellung automatisch erfolgt, und zwar in Abhängigkeit von der Container-Größe. Angenommen, Sie definieren folgendes Raster für den HTML-Code:
<span class="hljs-selector-class">.card</span> {
<span class="hljs-attribute">display</span>: grid;
<span class="hljs-attribute">grid-gap</span>: <span class="hljs-number">8px</span>;
<span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(auto-fit,
minmax(300px, 1fr));
}
Dann werden die Inhalte der .card in einem Raster dargestellt, bei dem die einzelnen Rasterzellen mindestens 300px breit sind. Das heißt, wenn weniger als 608px (2 * 300px + 1 * 8px grid-gap) zur Verfügung stehen, stehen Bild und Text untereinander, sonst nebeneinander. Damit wird die Bild-/Textkomponente, je nachdem, wo sie sich befindet und wie viel Platz dort zur Verfügung steht, passend dargestellt. Übrigens können Sie an diesem Beispiel auch gut erkennen, was der Unterschied zwischen auto-fit und auto-fill innerhalb der repeat()-Funktion ist: Wenn mehr Platz als 916px zur Verfügung steht, bleibt bei auto-fill noch Platz daneben für eine weitere Zelle mit 300px, die nicht ausgefüllt wird. Bei auto-fit hingegen wird dieser Platz auf die beiden Spalten aufgeteilt, so dass keine Lücke bleibt. Ein Problem hat der gerade gezeigte Code noch: Die 300px sind eine Mindestbreite, was bei weniger Platz zu Scrollbalken führen kann. Das lässt sich mithilfe der folgenden verbesserten Rasterdefinition verhindern:
grid-<span class="hljs-keyword">template</span>-columns: repeat(<span class="hljs-keyword">auto</span>-fit, minmax(<span class="hljs-built_in">min</span>(<span class="hljs-number">300</span>px, <span class="hljs-number">100</span>%), <span class="hljs-number">1</span>fr));
Hier wird als Mindestwert von minmax() die min()-Funktion genutzt. min(300px, 100%) wählt von den beiden übergebenen Werten den kleineren aus. Wenn beispielsweise nur 250px Platz zur Verfügung stehen, sind 100% kleiner als 300px, also wird in diesem Fall 100% genommen. So kann die Box auch schmaler als 300px werden.Diese Lösung ist praktisch, wenn genau diese Darstellungsart in Abhängigkeit vom verfügbaren Platz gewünscht wird. Aber was, wenn bei der Darstellung nebeneinander die Textkomponente doppelt so breit sein soll wie das Bild? Dafür bräuchte man eine Angabe wie span-minmax(), die festzulegt, über wie viel Rasterzellen eine Komponente mindestens oder maximal geht. Derzeit existiert das bei Gridlayout nicht. Mit Container Queries wäre das gewünschte Verhalten machbar und es wären auch alle weiteren Darstellungsvarianten möglich.
Flexbox verwenden
Sie können auch Flexbox für eine angepasste Darstellung je nach Containerbreite verwenden. Hierfür brauchen Sie folgenden Code für die Text-/Bildkomponente:
<span class="hljs-selector-class">.card</span> {
<span class="hljs-attribute">display</span>: flex;
<span class="hljs-attribute">gap</span>: <span class="hljs-number">8px</span>;
<span class="hljs-attribute">flex-wrap</span>: wrap;
}
<span class="hljs-selector-class">.card</span> > * {
<span class="hljs-attribute">flex-basis</span>: <span class="hljs-number">300px</span>;
<span class="hljs-attribute">flex-shrink</span>: <span class="hljs-number">1</span>;
<span class="hljs-attribute">flex-grow</span>: <span class="hljs-number">1</span>;
}
Wenn .content breiter werden soll, sofern genügend Platz zur Verfügung steht, ergänzen Sie zusätzlich flex-grow:
<span class="hljs-selector-class">.card</span> <span class="hljs-selector-class">.content</span> {
<span class="hljs-attribute">flex-grow</span>: <span class="hljs-number">2</span>;
}
Auch das Multicolumn-Layout stellt eine geeignete Lösung des Problems dar:
<span class="hljs-selector-class">.card</span> {
<span class="hljs-attribute">column-width</span>: <span class="hljs-number">300px</span>;
<span class="hljs-attribute">column-count</span>: <span class="hljs-number">2</span>;
<span class="hljs-attribute">column-gap</span>: <span class="hljs-number">8px</span>;
}
Wenn Sie column-count zusammen mit column-width definieren, legt column-count die maximale Anzahl an Spalten fest und column-width die optimale Breite – die Bereiche können allerdings auch schmaler werden. Damit haben wir einen automatischen Wechsel zwischen einspaltiger und zweispaltiger Darstellung. Der Text kann sich dabei aber auch unterhalb des Bildes befinden. Das lässt sich vermeiden über:
<span class="hljs-selector-class">.card</span> <span class="hljs-selector-class">.content</span> {
<span class="hljs-attribute">break-inside</span>: avoid;
}
Allerdings führt diese Ergänzung – zumindest in Chrome – in manchen Viewportgrößen dazu, dass eine zweite leere Spalte angezeigt wird.
Fazit
Container Queries haben das Zeug zum Game Changer. Unterschiedliche Darstellungen je nach verfügbarem umfassenden Container lassen sich zwar auch über Grid, Flexbox oder Multicolumn realisieren, aber das sind keine globalen Lösungen. Die werden schnell aufwändig, wenn man kleine Dinge variieren möchte, oder möglicherweise gar nicht funktionieren. Die Container Queries hingegen bieten eine einfache, intuitive Lösung für viele komponentenbasierte Layouts.Unabhängig davon lohnt sich der Einsatz der contain-Eigenschaft auf jeden Fall heute schon, weil sie die Performance verbessert.Links zum Thema
<b>◼ <a href="https://www.smashingmagazine.com/2019/12/browsers-containment-css-contain-property/" rel="noopener" target="_blank">Funktionsweise der contain-Eigenschaft</a> <br/></b>