Container Queries werden oft als moderner Ansatz für responsives Webdesign angesehen, bei dem traditionelle Media Queries lange Zeit der Goldstandard waren – der Grund dafür ist, dass wir Layouts mit Elementen erstellen können, die beispielsweise auf die Breite ihres Containers reagieren, anstatt auf die Breite des Viewports.
.parent {
container-name: hero-banner;
container-type: inline-size;
/* or container: hero-banner / inline-size; */
}
}
.child {
display: flex;
flex-direction: column;
}
/* When the container is greater than 60 characters... */
@container hero-banner (width > 60ch) {
/* Change the flex direction of the .child element. */
.child {
flex-direction: row;
}
}
Warum sollte man sich für CSS Container Queries interessieren?
- Durch die Verwendung einer Container Query geben wir Elementen die Fähigkeit, sich basierend auf der Größe ihres Containers zu verändern, nicht auf Basis des Viewports.
- Sie ermöglichen es uns, alle Stile für ein bestimmtes Element auf eine vorhersehbarere Weise zu definieren.
- Sie sind wiederverwendbarer als Media Queries, da sie sich überall dort gleich verhalten, wo sie eingesetzt werden. Wenn Sie also eine Komponente erstellen, die eine Container Query enthält, können Sie diese einfach in ein anderes Projekt einfügen, und sie wird sich weiterhin auf die gleiche vorhersehbare Weise verhalten.
- Sie führen neue Arten von CSS-Längeneinheiten ein, mit denen Elemente anhand der Größe ihres Containers skaliert werden können.
Elemente als Container registrieren
.cards {
container-name: card-grid;
container-type: inline-size;
/* Shorthand */
container: card-grid / inline-size;
}
Dieses Beispiel registriert einen neuen Container namens card-grid, der nach seiner inline-size abgefragt werden kann. Das ist eine schicke Art, „Breite“ zu sagen, wenn wir in einem horizontalen Schreibmodus arbeiten. Es handelt sich um eine logische Eigenschaft. Andernfalls würde sich „inline“ auf die „Höhe“ des Containers in einem vertikalen Schreibmodus beziehen.
- Die Eigenschaft
container-namewird verwendet, um ein Element als Container zu registrieren, der Stile auf andere Elemente basierend auf der Größe und den Stilen des Containers anwendet.
- Die Eigenschaft
container-typewird verwendet, um ein Element als Container zu registrieren, der Stile auf andere Elemente anwenden kann, wenn er bestimmte Bedingungen erfüllt.
- Die Eigenschaft
containerist eine Kurzschreibweise, die die Eigenschaftencontainer-nameundcontainer-typein einer einzigen Deklaration kombiniert.
Mögliche Fallstricke
- Die Eigenschaft
container-nameist optional. Ein unbenannter Container passt auf jede Container Query, die nicht auf einen spezifischen Container abzielt. Das bedeutet, er könnte mehrere Bedingungen erfüllen. - Die Eigenschaft
container-typeist erforderlich, wenn wir einen Container nach seinersizeoderinline-sizeabfragen wollen.sizebezieht sich auf die Inline- oder Block-Richtung des Containers, je nachdem, welche größer ist.inline-sizebezieht sich auf die Breite des Containers im standardmäßigen horizontalen Schreibmodus. - Der Standardwert der Eigenschaft
container-typeistnormal. Und mit „normal“ ist gemeint, dass alle Elemente standardmäßig Container sind, sie werden jedoch Style-Container genannt und können nur nach ihren angewandten Stilen abgefragt werden. Beispielsweise können wir den Wert derbackground-coloreines Containers abfragen und Stile auf andere Elemente anwenden, wenn der Wert einem bestimmten Farbwert entspricht. - Ein Container kann seine eigenen Stile nicht ändern. Stattdessen ändern sie die Stile ihrer Inhalte. Mit anderen Worten: Wir können die
background-colordes Containers nicht ändern, wenn er eine bestimmte Größe hat – aber wir können diebackground-colorjedes Elements innerhalb des Containers ändern. „Du kannst nicht stylen, was du abfragst“ ist eine gute Denkweise hierfür. - Die Größe eines Containers kann nicht durch seinen Inhalt bestimmt werden. Normalerweise beeinflusst der Inhalt eines Elements dessen Größe – je mehr Inhalt, desto größer das Element und umgekehrt. Ein Container muss jedoch explizit als Teil eines Flex- oder Grid-Layouts dimensioniert werden.
Einen Container abfragen
@container my-container (width > 60ch) {
article {
flex-direction: row;
}
}
- Die
@containerAt-Rule informiert den Browser, dass wir mit einer Container Query arbeiten und nicht etwa mit einer Media Query (z. B.@media).
- Der Teil
my-containerdarin bezieht sich auf den Namen des Containers, wie er in der Eigenschaftcontainer-namedeklariert wurde.
- Das
article-Element repräsentiert ein Element im Container, sei es ein direktes Kind des Containers oder ein weiter entfernter Nachfahre. In jedem Fall muss sich das Element im Container befinden, damit die Stile angewendet werden, wenn die abgefragte Bedingung erfüllt ist.
Mögliche Fallstricke
- Der Name des Containers ist optional. Wenn wir ihn weglassen, würde jeder registrierte Container passen, sobald die Bedingungen erfüllt sind.
- Die
widtheines Containers kann abgefragt werden, wenn die Eigenschaftcontainer-typeauf entwedersizeoderinline-sizegesetzt ist. Das liegt daran, dasssizediewidthoderheightdes Elements abfragen kann; währendinline-sizesich nur auf diewidthbeziehen kann. - Sie können jede Länge abfragen. Zusätzlich zur
width(d. h.inline-size) gibt es dasaspect-ratioeines Elements, dieblock-size(d. h.height) und die Orientierung (z. B.portraitundlandscape). - Abfragen unterstützen die Bereichssyntax (Range Syntax). Die meisten bisherigen Beispiele zeigten „größer als“ (
>) und „kleiner als“ (<), aber es gibt auch „gleich“ (=) sowie Kombinationen der drei, wie „größer als oder gleich“ (>=) und „kleiner als oder gleich“ (<=). - Abfragen können verkettet werden. Das bedeutet, wir können Abfragen schreiben, die mehrere Bedingungen mit logischen Schlüsselwörtern wie
and,orundnoterfüllen.
Eigenschaften & Werte von Container Queries
Eigenschaften & Werte von Container Queries
container-name
container-name: none | <custom-ident>+;
Wertbeschreibungen
none: Das Element hat keinen Containernamen. Dies ist standardmäßig der Fall, sodass Sie diesen Wert wahrscheinlich nie explizit verwenden werden, da sein Zweck lediglich darin besteht, das Standardverhalten der Eigenschaft festzulegen.<custom-ident>: Dies ist der Name des Containers, der alles Mögliche sein kann, außer Wörter, die für andere Funktionen reserviert sind, einschließlichdefault,none,at,noundor. Beachten Sie, dass die Namen nicht in Anführungszeichen gesetzt werden.
- Initialwert:
none - Anwendbar auf: Alle Elemente
- Vererbt: Nein
- Prozentangaben: N/A
- Berechneter Wert:
noneoder eine geordnete Liste von Bezeichnern - Kanonische Reihenfolge: Gemäß Grammatik
- Animation: Nicht animierbar
container-type
container-type: normal | size | inline-size;
Wertbeschreibungen
normal: Dies gibt an, dass das Element ein Container ist, der nach seinen Stilen statt nach der Größe abgefragt werden kann. Alle Elemente sind technisch gesehen standardmäßig Container, daher müssen wir nicht einmal explizit einencontainer-typezuweisen, um einen Style-Container zu definieren.size: Dies wird verwendet, wenn wir einen Container nach seiner Größe abfragen möchten, unabhängig davon, ob es sich um die Inline- oder Block-Richtung handelt.inline-size: Dies ermöglicht es uns, einen Container nach seiner Inline-Größe abzufragen, was derwidthin einem standardmäßigen horizontalen Schreibmodus entspricht. Dies ist vielleicht der am häufigsten verwendete Wert, da wir so responsive Designs basierend auf der Elementgröße erstellen können, anstatt auf der Viewport-Größe, wie wir es normalerweise mit Media Queries tun würden.
- Initialwert:
normal - Anwendbar auf: Alle Elemente
- Vererbt: Nein
- Prozentangaben: N/A
- Berechneter Wert: Wie durch das Schlüsselwort spezifiziert
- Kanonische Reihenfolge: Gemäß Grammatik
- Animation: Nicht animierbar
container
container: <'container-name'> [ / <'container-type'> ]?
Wertdefinitionen
Wenn <'container-type'> weggelassen wird, wird es auf seinen Initialwert normal zurückgesetzt, was einen Style-Container anstelle eines Size-Containers definiert. Mit anderen Worten: Alle Elemente sind standardmäßig Style-Container, es sei denn, wir setzen den Wert der Eigenschaft container-type explizit auf size oder inline-size, was uns erlaubt, die Größenabmessungen eines Containers abzufragen.
- Initialwert:
none/normal - Anwendbar auf: Alle Elemente
- Vererbt: Nein
- Prozentangaben: N/A
- Berechneter Wert: Wie spezifiziert
- Kanonische Reihenfolge: Gemäß Grammatik
- Animation: Nicht animierbar
Container-Längeneinheiten
Einheiten für Container-Breite & -Höhe
| Einheit | Name | Entspricht… |
|---|---|---|
cqw | Container Query Breite (Width) | 1% der Breite des abgefragten Containers |
cqh | Container Query Höhe (Height) | 1% der Höhe des abgefragten Containers |
Logische Richtungen des Containers
| Einheit | Name | Entspricht… |
|---|---|---|
cqi | Container Query Inline-Größe | 1% der Inline-Größe des abgefragten Containers, was im horizontalen Schreibmodus seiner Breite entspricht. |
cqb | Container Query Block-Größe | 1% der Block-Größe des abgefragten Containers, was im horizontalen Schreibmodus seiner Höhe entspricht. |
Minimale & maximale Längen des Containers
| Einheit | Name | Entspricht… |
|---|---|---|
cqmin | Minimale Größe der Container Query | Der Wert von cqi oder cqb, je nachdem, welcher kleiner ist. |
cqmax | Maximale Größe der Container Query | Der Wert von cqi oder cqb, je nachdem, welcher größer ist. |
Container Style Queries
Container Style Queries sind ein weiteres Puzzleteil der CSS Container Queries. Anstatt einen Container nach seiner size oder inline-size abzufragen, können wir die CSS-Stile eines Containers abfragen. Wenn die Stile des Containers die abgefragte Bedingung erfüllen, können wir Stile auf andere Elemente anwenden. Dies ist die Art von „bedingtem“ Styling, die wir uns im Web schon lange gewünscht haben: Wenn diese Stile hier übereinstimmen, dann wende diese anderen Stile dort an.
CSS Container Style Queries sind zum Zeitpunkt der Erstellung dieses Artikels nur als experimentelles Feature in modernen Webbrowsern verfügbar, und selbst dann sind Style Queries nur in der Lage, benutzerdefinierte CSS-Eigenschaften (d. h. Variablen) auszuwerten.
Browser-Unterstützung
Das Feature gilt zum Zeitpunkt der Erstellung dieses Dokuments noch als experimentell und wird von keinem Browser unterstützt, es sei denn, es wird über Feature-Flags aktiviert.
Diese Daten zur Browser-Unterstützung stammen von Caniuse, wo weitere Details zu finden sind. Eine Zahl gibt an, dass der Browser das Feature ab dieser Version unterstützt.
Desktop
| Chrome | Firefox | IE | Edge | Safari |
|---|---|---|---|---|
| 130 | Nein | Nein | 127 | TP |
Mobil / Tablet
| Android Chrome | Android Firefox | Android | iOS Safari |
|---|---|---|---|
| 127 | Nein | 127 | 18.0 |
Einen Style-Container registrieren
article {
container-name: card;
}
Das ist eigentlich schon alles! Tatsächlich benötigen wir die Eigenschaft container-name gar nicht, es sei denn, wir müssen ihn gezielt ansprechen. Andernfalls können wir die Registrierung eines Containers komplett überspringen.
Und falls Sie sich fragen, warum es keine container-type-Deklaration gibt: Das liegt daran, dass alle Elemente bereits als Container betrachtet werden. Das ist ähnlich wie die Tatsache, dass alle Elemente standardmäßig position: relative sind; man muss es nicht deklarieren. Der einzige Grund, einen container-type zu deklarieren, ist, wenn wir eine CSS Container Size Query anstelle einer CSS Container Style Query wünschen.
Es gibt also wirklich keine Notwendigkeit, eine Container Style Query zu registrieren, da alle Elemente von Haus aus bereits Style-Container sind! Der einzige Grund, container-name zu deklarieren, wäre also lediglich, um beim Schreiben einer Style Query einen bestimmten Container namentlich auswählen zu können.
Verwendung einer Style Container Query
@container style(--bg-color: #000) {
p { color: #fff; }
}
In diesem Beispiel fragen wir einen beliebigen passenden Container ab (da alle Elemente standardmäßig Style-Container sind).
Fällt Ihnen auf, dass die Syntax sehr stark einer traditionellen Media Query ähnelt? Der größte Unterschied ist, dass wir @container anstelle von @media schreiben. Der andere Unterschied ist, dass wir eine style()-Funktion aufrufen, welche die passende Stilbedingung enthält. Auf diese Weise wird eine Style Query von einer Size Query unterschieden, obwohl es keine entsprechende size()-Funktion gibt.
In diesem Fall prüfen wir, ob eine bestimmte benutzerdefinierte Eigenschaft namens --bg-color auf Schwarz (#000) gesetzt ist. Wenn der Wert der Variable dieser Bedingung entspricht, setzen wir die Textfarbe (color) des Absatzes (p) auf Weiß (#fff).
Benutzerdefinierte Eigenschaften & Variablen
.card-wrapper {
--bg-color: #000;
}
.card {
@container style(--bg-color: #000) {
/* Custom CSS */
}
}
Verschachtelung von Style Queries
@container style(--featured: true) {
article {
grid-column: 1 / -1;
}
@container style(--theme: dark) {
article {
--bg-color: #000;
--text: #fff;
}
}
}
Spezifikation
CSS Container Queries sind in der CSS Containment Module Level 3 Spezifikation definiert, die sich zum Zeitpunkt der Erstellung dieses Artikels im Status „Editor’s Draft“ befindet.
Browser-Unterstützung
Die Browser-Unterstützung für CSS Container Size Queries ist hervorragend. Lediglich für Style Queries fehlt zum Zeitpunkt der Erstellung dieses Artikels noch die breite Unterstützung.
- Chrome 105 wurde am 30. August 2022 mit Unterstützung veröffentlicht.
- Safari 16 wurde am 12. September 2022 mit Unterstützung veröffentlicht.
- Firefox 110 wurde am 14. Februar 2023 mit Unterstützung veröffentlicht.
Diese Daten zur Browser-Unterstützung stammen von Caniuse, wo weitere Details verfügbar sind. Eine Zahl gibt an, dass der Browser das Feature ab dieser Version unterstützt.
Desktop
| Chrome | Firefox | IE | Edge | Safari |
|---|---|---|---|---|
| 106 | 110 | Nein | 106 | 16.0 |
Mobil / Tablet
| Android Chrome | Android Firefox | Android | iOS Safari |
|---|---|---|---|
| 127 | 127 | 127 | 16.0 |
Demos!
Es gibt im Web viele Beispiele, die demonstrieren, wie Container Queries funktionieren. Die folgenden Beispiele sind in dieser Hinsicht nicht einzigartig, da sie das allgemeine Konzept veranschaulichen, Stile anzuwenden, wenn ein Container-Element eine bestimmte Bedingung erfüllt.
Viele weitere Beispiele finden Sie in den Referenzen am Ende dieses Guides, aber schauen Sie sich das Container Queries Lab von Ahmad Shadeed für die vollständigste Sammlung an, da es auch als Sammlung cleverer Anwendungsfälle für Container Queries dient.
Card-Komponente
In diesem Beispiel ändert eine „Card“-Komponente ihr Layout basierend auf dem verfügbaren Platz in ihrem Container.
Call-to-Action Panel
Dieses Beispiel ähnelt kleinen Panels für die Anmeldung zu einem E-Mail-Newsletter. Beachten Sie, wie sich das Layout dreimal ändert, je nachdem, wie viel Platz im Container verfügbar ist. Das ist es, was CSS Container Queries so mächtig macht: Sie können dieses Panel buchstäblich in jedes Projekt einfügen und das Layout wird wie gewünscht reagieren, da es auf dem verfügbaren Platz und nicht auf der Größe des Viewports basiert.
Stepper-Komponente
Diese Komponente zeigt eine Reihe von „Schritten“ ähnlich einer Zeitachse an. In breiteren Containern zeigt der Stepper die Schritte horizontal an. Wenn der Container jedoch klein genug wird, verschiebt der Stepper die Elemente so, dass die Schritte vertikal untereinander stehen.
Icon-Button
Manchmal schmücken wir Buttons mit einem Icon aus, um die Beschriftung des Buttons mit etwas mehr Bedeutung und Kontext zu unterstreichen. Und manchmal wissen wir nicht genau, wie breit dieser Button in einem bestimmten Kontext sein wird. Das macht es schwierig zu wissen, wann genau das Icon ausgeblendet oder das Design des Buttons angepasst werden soll, wenn der Platz knapp wird. In diesem Beispiel wird ein Icon am rechten Rand des Buttons angezeigt, solange Platz neben der Beschriftung vorhanden ist. Wenn der Platz nicht mehr ausreicht, wird der Button zu einer quadratischen Kachel, bei der die Icons über der Beschriftung gestapelt sind. Beachten Sie, wie der border-radius in Container-Query-Einheiten (4cqi) definiert ist. Dies entspricht 4 % der Inline-Größe (Breite) des Containers und führt dazu, dass die Kanten mit zunehmender Buttongröße runder werden.
Pagination (Seitennummerierung)
Die Pagination ist ein hervorragendes Beispiel für eine Komponente, die von CSS Container Queries profitiert. Je nach verfügbarem Platz können wir wählen, ob wir Links zu einzelnen Seiten anzeigen oder diese zugunsten von nur zwei Buttons ausblenden – einen für ältere Inhalte und einen für neuere Inhalte.
Artikel & Tutorials
Allgemeine Informationen
Sagen Sie „Hallo“ zu CSS Container Queries
Die Entstehungsgeschichte von Container Queries
Ein Füllhorn an Container Queries
Diskussion zu Container Queries
Container Queries: Noch einmal auf in die Bresche
CSS der nächsten Generation: @container
251: Container Queries sind die Zukunft
Lasst uns die Container Queries nicht vergessen
Minimale Ansätze zur Simulation von Container Queries
Die Raven-Technik: Ein Schritt näher an Container Queries
Tutorials zu Container-Größen-Queries
Media Queries in Zeiten von @container
Können wir einen „Resize Hack“ mit Container Queries erstellen?
Einige Male, in denen mir Container-Größen-Queries geholfen hätten
Ein neues Container Query Polyfill, das einfach funktioniert
256: Wann man @container Queries verwendet
iShadeeds Container Queries Lab
Minimale Ansätze zur Simulation von Container Queries
Experimentieren mit (fake) Container Queries mit watched-box & resizeasaurus
Container-Stil-Queries
Referenzen
- Container Queries: Eine Schnellstart-Anleitung (OddBird)
- CSS-Container, was wissen sie? (OddBird)
- Eine Einführung in CSS Container Queries (Smashing Magazine)
- CSS Container Queries: Anwendungsfälle und Migrationsstrategien (Smashing Magazine)
- Ein interaktiver Leitfaden zu CSS Container Queries (und Demos) (Ahmad Shadeed)
- Container Queries – Designing in the Browser (web.dev)
- CSS Container Queries (Mozilla Developer Network)
- Container Queries werden die Art, wie wir Layouts erstellen, verändern (Kevin Powell)
- Container Queries und Einheiten (Zach Saucier)
- Container Query Einheiten und fluide Typografie (ModernCSS)
Hallo. Danke für die Erinnerung an Container Queries.
Sind nicht alle Elemente standardmäßig auf
staticpositioniert?Ja, dieser Teil hat mich kurz verwirrt. Ich musste prüfen, ob sich die Spezifikationen irgendwie geändert haben! Aber ja, alle Element-Positionen sind standardmäßig immer noch statisch, nicht relativ.
Aber es ist immer noch unmöglich, eine Regel zu erstellen, die es erlaubt, bestimmte Stile anzuwenden, wenn die Höhe des Containers bestimmte Werte hat, oder?
Nur ein kurzes Beispiel
Hier sehen wir, wie wir oft Container Queries für responsive Layouts nutzen
Aber stellen wir uns vor, wir müssten etwas tun, wenn unsere Karte zu hoch wird, zum Beispiel einen Nebel-Ausblendeffekt erstellen
Das wird nicht funktionieren, da wir
inline-sizeals Typ für den Containercardverwenden. Wenn wir aber den Typ aufsizeändern, müssen wir eine feste Höhe für den Container verwenden (aber wir wissen eigentlich nicht, welche Höhe er auf der Seite haben wird, da der Inhalt unterschiedlich ist, und wir wollen nur unsere Karten vor Übergröße schützen, den Inhalt ausblenden, zusätzliche UI-Elemente anzeigen usw.).Eine Frage zu einem Problem, auf das ich stoße. Wenn ich eine Liste von Karten verwende, bei der jede Karte mittels Container Query angezeigt wird, und ich einen Tooltip (NuxtUI-Bibliothek) nutze, erscheint der Text der nächsten Karte vor diesem Tooltip, falls er ihn überlappt. Der Tooltip erscheint korrekt, wenn ich den „Container Query“-Teil von der Karte entferne. Liegt das an der Stapelreihenfolge (Stacking Order)? Oder gibt es dafür eine Lösung?