Chrome experimentiert mit @container, einer Eigenschaft innerhalb der Containment Level 3 Spezifikation der CSS Working Group, die von Miriam Suzanne von Oddbird und einer Gruppe von Ingenieuren der gesamten Web-Plattform vorangetrieben wird. @container gibt uns die Fähigkeit, Elemente basierend auf der Größe ihres Elternelements zu stylen.
Sie können sich diese wie eine Media Query (@media) vorstellen, aber anstatt sich auf das Viewport zu verlassen, um Styles anzupassen, kann das Elternelement des von Ihnen angesprochenen Elements diese Styles anpassen.
Container Queries werden die größte Veränderung im Web-Styling seit CSS3 sein und unsere Perspektive auf „Responsive Design“ verändern.
Der Viewport und der User-Agent werden nicht mehr die einzigen Ziele sein, auf die wir uns verlassen können, um Responsive Layout- und UI-Styles zu erstellen. Mit Container Queries können Elemente ihre eigenen Eltern ansprechen und ihre eigenen Styles entsprechend anwenden. Das bedeutet, dass dasselbe Element, das sich in der Seitenleiste, im Hauptteil oder im Hero-Bereich befindet, je nach verfügbarer Größe und Dynamik völlig unterschiedlich aussehen kann.
@container in Aktion
In diesem Beispiel verwende ich zwei Karten innerhalb eines Elternelements mit folgendem Markup
<div class="card-container">
<div class="card">
<figure> ... </figure>
<div>
<div class="meta">
<h2>...</h2>
<span class="time">...</span>
</div>
<div class="notes">
<p class="desc">...</p>
<div class="links">...</div>
</div>
<button>...</button>
</div>
</div>
</div>
Anschließend setze ich die Containment (die container-type Eigenschaft) für das Elternelement, auf dem ich die Container-Styles abfragen werde (.card-container). Ich setze auch ein relatives Grid-Layout auf das Elternelement von .card-container, sodass sich dessen inline-size basierend auf diesem Grid ändert. Dies frage ich mit @container ab.
.card-container {
container-type: inline-size;
width: 100%;
}
Jetzt kann ich Container-Styles abfragen, um Styles anzupassen! Dies ist sehr ähnlich dazu, wie Sie Styles mit breitenbasierten Media Queries einstellen würden, wobei max-width verwendet wird, um Styles festzulegen, wenn ein Element kleiner als eine bestimmte Größe ist, und min-width, wenn es größer ist.
/* when the parent container is smaller than 850px,
remove the .links div and decrease the font size on
the episode time marker */
@container (max-width: 850px) {
.links {
display: none;
}
.time {
font-size: 1.25rem;
}
/* ... */
}
/* when the parent container is smaller than 650px,
decrease the .card element's grid gap to 1rem */
@container (max-width: 650px) {
.card {
gap: 1rem;
}
/* ... */
}
Container Queries + Media Queries
Eines der besten Features von Container Queries ist die Möglichkeit, Mikrolayouts von Makrolayouts zu trennen. Sie können einzelne Elemente mit Container Queries stylen und so nuancierte Mikrolayouts erstellen, und ganze Seitenlayouts mit Media Queries stylen, dem Makrolayout. Dies schafft eine neue Ebene der Kontrolle, die noch responsivere Interfaces ermöglicht.
Hier ist ein weiteres Beispiel, das die Stärke der Verwendung von Media Queries für Makrolayouts (d.h. der Kalender geht von Einzelpanel zu Mehrpanel) und Mikrolayouts (d.h. das Layout/die Größe des Datums und die Ränder/die Größe des Events verschieben sich) zeigt, um ein wunderschönes Zusammenspiel von Queries zu schaffen.
Container Queries + CSS Grid
Eine meiner persönlichen Lieblingsmethoden, um die Auswirkungen von Container Queries zu sehen, ist zu beobachten, wie sie innerhalb eines Grids funktionieren. Betrachten Sie das folgende Beispiel einer Pflanzenhandels-UI
Auf dieser Website werden überhaupt keine Media Queries verwendet. Stattdessen verwenden wir nur Container Queries zusammen mit CSS Grid, um die Shopping-Card-Komponente in verschiedenen Ansichten anzuzeigen.
Im Produkt-Grid wird das Layout mit grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); erstellt. Dies erzeugt ein Layout, das den Karten sagt, dass sie den verfügbaren Bruchteil der Fläche einnehmen sollen, bis sie eine Größe von 230px erreichen, und dann zur nächsten Zeile fließen sollen. Schauen Sie sich weitere Grid-Tricks auf 1linelayouts.com an.
Dann haben wir eine Container Query, die die Karten so stylt, dass sie ein vertikales Blocklayout annehmen, wenn sie weniger als 350px breit sind, und zu einem horizontalen Inline-Layout wechseln, indem sie display: flex anwenden (was standardmäßig einen Inline-Flow hat).
@container (min-width: 350px) {
.product-container {
padding: 0.5rem 0 0;
display: flex;
}
/* ... */
}
Das bedeutet, dass jede Karte ihr eigenes responsives Styling besitzt. Dies ist ein weiteres Beispiel dafür, wie Sie ein Makrolayout mit dem Produkt-Grid und ein Mikrolayout mit den Produktkarten erstellen können. Ziemlich cool!
Verwendung
Um @container verwenden zu können, müssen Sie zuerst ein Elternelement erstellen, das Containment hat. Dazu müssen Sie contain: layout inline-size auf dem Elternelement setzen. Sie können inline-size verwenden, da wir Container Queries derzeit nur auf der Inline-Achse anwenden können. Dies verhindert, dass Ihr Layout in Blockrichtung bricht.
Das Setzen von contain: layout inline-size erstellt einen neuen Containing Block und einen neuen Block Formatting Context, wodurch der Browser ihn vom Rest des Layouts trennt. Jetzt können wir abfragen!
Einschränkungen
Derzeit können Sie keine höhenbasierten Container Queries verwenden, nur die Blockachse. Damit Grid-Kinder mit @container funktionieren, müssen Sie ein Wrapper-Element hinzufügen. Trotzdem können Sie mit dem Hinzufügen eines Wrappers die gewünschten Effekte erzielen.
Probieren Sie es aus
Sie können heute mit der @container Eigenschaft in Chromium experimentieren, indem Sie in Chrome Canary zu: chrome://flags navigieren und das Flag #experimental-container-queries aktivieren.

Kann man mehrere Container abfragen?
Ich glaube nicht, aber ich bin gerade dabei, mir das alles zu erschließen. Ich glaube, in der aktuellen Spezifikation kann man nicht einmal einen Container spezifizieren. Es wird einfach angenommen, dass Sie das Elternelement meinen, von allem, was Sie darin auswählen.
Ja! Sie können Containment für mehr als ein Elternelement festlegen und diese Elternelemente abfragen.
Also schreiben wir Queries innerhalb von
@container, die auf den einzelnen Container verweisen, bei dem diecontainEigenschaft spezifiziert ist. Wie würde das funktionieren, wenn man mehrere Container haben möchte?Alle Elemente, die von einem Selektor innerhalb von
@containerangesprochen werden, fragen ihren nächsten Elternelement-Container ab. Wenn Sie also sowohl.sidebarals auchmainals Container einrichten, können Sie Elemente in beide einfügen, und jedes Element fragt den Container ab, in dem es sich befindet. Sie können Container so tief verschachteln, wie Sie möchten, und Elemente werden immer den nächstgelegenen abfragen.Es fühlt sich so seltsam an, daran zu denken, dass das endlich wahr wird.
Vielen Dank an alle Beteiligten, die dies möglich gemacht haben!
Container Queries, Grid und Web Components, uns kann jetzt nichts mehr aufhalten (halt die Klappe Safari!)
Cool! Gibt es eine Möglichkeit, verschiedene Container zu haben? Oder müsste man etwas wie die Referenzierung des Elternelements im Selektor tun?
Ja! Sie können Containment für mehr als ein Elternelement festlegen und diese Elternelemente abfragen.
Ich hoffe, das wird bald finalisiert, es ist der heilige Gral, um UI-Komponenten wiederverwendbar zu machen.
Ich frage mich, wie weit es noch von der Einführung in die offizielle Chrome-Version entfernt ist.
Es wird großartig sein, dies als native CSS-Funktion zu haben!
Bis dahin gibt es glücklicherweise Bibliotheken :)
In dieser Demo zum Beispiel gibt es viele Container Queries
https://tobireif.com/demos/grid/
Es verwendet die Bibliothek https://github.com/eqcss/eqcss/ und deren Syntax.
sehr cool Tobi
Es ist also mehr oder weniger ein CSS-Äquivalent zum Resize Observer – etwas, das ich mir schon lange gewünscht habe!
Das Polyfill verwendet Resize Observer :) https://github.com/jsxtools/cqfill
Hey. Die Einschränkung, @container auf ein Grid-Element anzuwenden. Wird das etwas sein, womit wir uns in der finalen Version von Container Queries auseinandersetzen müssen, oder wird es eine Möglichkeit geben, ein Grid-Element zu einem Container zu machen, ohne ein zusätzliches Wrapper-Element hinzufügen zu müssen?
Danke!
Das klingt nach einem Trick, den ich für eine Friedhofs-Website verwenden kann, indem ich das Grid für einzelne Gräber nutze und Abfragen verwende, um die Menge und Art der Informationen über die dort bestatteten Personen je nach Größe zu ändern. Aufregend!
Ich gehe davon aus, dass dies jahrelang im experimentellen Bereich verbleiben wird, genau wie backdrop-filter. Etwas, das wir wirklich wollen, das wahrscheinlich schon perfekt funktioniert, aber das wir jahrelang nicht sehen werden.
Ich hoffe, ich irre mich, aber ich würde 100 $ darauf wetten, dass es mindestens ein Jahr dauern wird.