Wir befinden uns noch in einem gaaaanz frühen Stadium der Container Queries. Zu früh für eine breite Browser-Unterstützung, aber Chromium unterstützt sie bereits, Safari hat die Unterstützung in Version 16 gestartet, und Firefox wird vermutlich bald folgen.
Die meisten frühen Gespräche über Container-Abfragen vergleichen die Syntax normalerweise mit Media-Abfragen.
/* Stacked flex container */
.post {
display: flex;
flex-direction: column;
}
/* Change direction when viewport is 600px or wider */
@media(min-width: 600px) {
.post {
flex-direction: row;
}
}
/* Define the container */
.posts {
container-name: posts;
container-type: inline-size;
}
.post {
display: flex;
flex-direction: column;
}
/* Query the container's min-width */
@container posts (min-width: 600px) {
/* Change styles when `posts` container is 600px or wider */
.post {
flex-direction: row;
}
}
Beide fragen nach min-width: 600. Der Unterschied besteht darin, dass die Media-Abfrage die Breite des Viewports betrachtet, um Stiländerungen auszulösen, während die Container-Abfrage die berechnete Breite des .posts-Elements betrachtet. Super!
Aber nach dem Anhören von CSS Podcast Episode 59 haben Una und Adam über die Zukunft von Container-Abfragen gesprochen: Style-Abfragen! Der aktuelle Arbeitsentwurf des CSS Containment Module Level 3 Spezifikation definiert Container-Style-Abfragen
Eine Container-Style-Abfrage ermöglicht das Abfragen der berechneten Werte des Abfragecontainers. Es ist eine boolesche Kombination einzelner Style-Features (<style-feature>), die jeweils eine einzelne, spezifische Eigenschaft des Abfragecontainers abfragen.
Aber noch keine Beispiele für die Syntax – nur eine kurze Beschreibung
Die Syntax eines <style-feature> ist die gleiche wie für eine Deklaration, und seine Abfrage ist wahr, wenn der berechnete Wert der gegebenen Eigenschaft im Abfragecontainer mit dem gegebenen Wert übereinstimmt (der ebenfalls bezüglich des Abfragecontainers berechnet wird), unbekannt, wenn die Eigenschaft oder ihr Wert ungültig oder nicht unterstützt ist, und andernfalls falsch. Die boolesche Syntax und Logik zur Kombination von Style-Features zu einer Style-Abfrage ist die gleiche wie für CSS-Feature-Abfragen. (Siehe @supports.)
Also ja, mit der Zeit sollten wir erwarten können, etwas Ähnliches zu tun
.posts {
container-name: posts;
}
@container posts (background-color: #f8a100) {
/* Change styles when `posts` container has an orange background */
.post {
color: #fff;
}
}
Das ist ein ziemlich dummes Beispiel. Eine Sache, die man beachten sollte, ist, dass der container-type nicht mehr auf der inline-size des Containers basiert, sondern auf style. Das könnten wir so deklarieren
.posts {
container-name: posts;
container-type: style; /* unnecessary */
}
…aber alle Container-Abfragen sind standardmäßig style-Abfragen. Nun ja, zumindest nach heutigem Stand. Miriam Suzanne hat eine schöne Übersicht über mögliche Probleme, die auftreten könnten.
Wo könnte das Abfragen von Container-Stilen nützlich sein? Das weiß ich noch nicht! Aber mein Geist geht an ein paar Stellen
- Benutzerdefinierte Eigenschaftswerte: Wir haben benutzerdefinierte Eigenschaften als Statusindikatoren verwendet, wie z. B. die von Ana vor einiger Zeit behandelte DRY-Switching-Methode (DRY-Switching with CSS Variables: The Difference of One Declaration). Der Wert ändert sich, und damit auch die Stile.
- Alternative Dark-Mode-Ansatz: Anstatt alles auf eine Änderung der Body-Klasse zu stützen, die benutzerdefinierte Eigenschaftswerte neu zuweist, können wir vielleicht eine ganze Farbpalette ändern, wenn sich beispielsweise die Hintergrundfarbe des Bodys ändert.
- Komplexere Abfragebedingungen: Wenn wir beispielsweise Stile anwenden möchten, wenn die
size- *und*style-Bedingungen für einen Container erfüllt sind.
Una erwähnte auch im CSS-Podcast, dass Container-Style-Abfragen einige unangenehme Styling-Situationen verhindern könnten, z. B. wenn wir kursiv geschriebenen Text in einem bereits kursiv geschriebenen blockquote hätten
blockquote {
container-name: quote;
}
@container quote (font-style: italic) {
em, i, q, address {
font-style: normal;
}
}
scheint unnötig kompliziert. Warum nicht
@container .posts (min-width: 600px) {
// Gilt für .posts
}
Kein Klugscheißen, versuche wirklich, die Logik zu finden…
Das wäre super cool und viel effizienter. Aber ich verstehe auch, dass es Dinge gibt, die CSS im Voraus wissen muss, und eines davon ist die Möglichkeit, eine Container-Deklaration mit einem Element abzugleichen, das explizit als Container definiert ist – ganz zu schweigen davon, welche Art von Abfrage wir wollen, sei es die Größe oder der Stil dieses Containers. Wir müssen CSS das mitteilen, damit der Browser weiß, wie die Dinge abgeglichen werden.
Der Selektor „.posts“ könnte theoretisch mehrere HTML-Knoten ansprechen, die jeweils das Attribut class auf posts gesetzt haben. In diesem Fall wäre nicht klar, welche Containerbreite in der Abfrage geprüft werden sollte.
Ich kann mir vorstellen, dass die CSS-Eigenschaft „container-name“ dazu dient, sicherzustellen, dass es nur einen Container mit einem bestimmten Namen geben kann.
Ich vermute, dass
.postundcontainer-name: posts;im Beispiel zufällig denselben Namen verwenden, aber in realen Fällen muss das nicht so sein und derselbecontainer-namewird in mehreren Klassenselektoren verwendet.Die Antworten hier fassen einige der Gründe zusammen. Wie Geoff vorschlägt, müssen wir Container explizit definieren – es gibt also kein Entkommen vor diesem Schritt, selbst wenn wir Selektoren in der
@container-Syntax verwenden würden.Aber auch: Namen sind optional, wiederverwendbar für verschiedene Elemente und ein Container kann mehrere Namen haben. Das erhöht die Flexibilität erheblich.
Sie müssen Containern keinen Namen geben und müssen keinen Namen in der Abfragesyntax erwähnen. Wenn kein Name zur Bedingung hinzugefügt wird, wird der nächste gültige Eltercontainer abgefragt. Wenn Sie nur den unmittelbar relevantesten Kontext wissen möchten, lassen Sie den Namen weg.
Sie können denselben Namen für mehrere Selektoren verwenden, um eine „Klasse“ von Containern zu erstellen. Sie könnten also dem Hauptbereich, der Seitenleiste, den Beiträgen, den Gitterelementen usw. den Namen des
layout-Containers hinzufügen. Dann können Sie den nächstenlayout-Container abfragen.Sie können einem einzelnen Container mehrere Namen zuweisen, damit er Teil mehrerer Muster ist. So könnten wir sagen, der Hauptbereich ist ein Container, der Teil unseres
layout-Musters ist, ihm aber auch den Namenmainund den Namencolor-contextgeben, weil er ein einzigartiges Farbschema anwendet. Jetzt können wir einige Abfragen schreiben, die spezifisch für den Namen desmain-Bereichs sind, einige, die nach dem nächstenlayoutsuchen, und einige, die nach dem nächstencolor-contextsuchen – und der Hauptbereich ist so konfiguriert, dass er all diese Abfragen verarbeiten kann.