CSS Container Queries
Nesting hält Komponentenselektoren zusammen. Media Queries beobachten weiter den Viewport. Container Queries stellen eine andere Frage: Wie breit ist dieser Elternkasten? So bleibt eine Produktkarte in einer schmalen Rail kompakt und öffnet sich in der breiten Hauptspalte — auch wenn sich das Browserfenster nicht geändert hat.
Warum der Viewport nicht reicht
Layouts setzen oft dieselbe Komponente in unterschiedlich breite Slots: eine 16rem-Sidebar und ein flexibler Hauptbereich. Beide teilen sich eine Viewport-Breite, also feuert @media (min-width: …) für beide gleich. Du brauchst Styles, die vom Container um die Karte abhängen, nicht vom ganzen Bildschirm.
Einen Mess-Kontext schaffen
Wähle den Eltern, der seine Größe melden soll. Setze container-type — meist inline-size, damit Abfragen die Inline-Größe des Elterns nutzen (Breite bei horizontaler Schrift), ohne gleich volle Größen-Containment auf beiden Achsen zu erzwingen:
.rail {
container-type: inline-size;
container-name: rail;
width: 16rem;
padding: 1rem;
background: #f8fafc;
}
.stage {
container-type: inline-size;
container-name: stage;
flex: 1;
min-width: 0;
padding: 1.25rem;
}
Ohne container-type hat @container nichts Zuverlässiges zum Messen. container-name ist optional, aber stark, wenn mehrere Vorfahren Container sind — dann zielst du gezielt auf einen Namen.
Den Container mit @container abfragen
Nach dem Setup packst du Regeln in @container mit einer Größenbedingung. Nachkommen reagieren, wenn dieser Kasten passt — nicht automatisch, wenn sich der Viewport ändert:
.product-card {
display: grid;
gap: 0.75rem;
padding: 1rem;
border: 1px solid #e2e8f0;
border-radius: 0.75rem;
background: #fff;
}
.product-card .media {
aspect-ratio: 16 / 10;
border-radius: 0.5rem;
background: #cbd5e1;
}
.product-card .meta {
font-size: 0.875rem;
color: #64748b;
}
@container (min-width: 28rem) {
.product-card {
grid-template-columns: 10rem 1fr;
align-items: center;
}
.product-card .title {
font-size: 1.25rem;
}
}
In einer schmalen .rail bleibt die Karte einspaltig gestapelt. Dasselbe Markup in einer breiten .stage — Zweispalten-Layout — gleiches HTML, gleicher Viewport, anderer Container-Breite.
Benannte Container
Wenn verschachtelte Container unklar lassen, welcher Kasten gilt, setzt du den Namen hinter @container:
@container stage (min-width: 36rem) {
.product-card {
grid-template-columns: 12rem 1fr auto;
gap: 1.25rem;
}
.product-card .buy {
justify-self: end;
}
}
@container rail (max-width: 18rem) {
.product-card .meta {
display: none;
}
}
@container stage (…) schaut nur auf Vorfahren mit dem Namen stage. Enge Rail-Regeln prallen nicht mit großzügigen Stage-Regeln zusammen, wenn beide dasselbe Markup umschließen.
Container-Query-Einheiten
Mit Containment-Kontext skalieren Längen wie cqi (1 % der Inline-Größe des Query-Containers) und cqw (1 % seiner Breite) Typo und Abstände mit dem Eltern, nicht dem Viewport (vi / vw):
.product-card .title {
font-size: clamp(1rem, 0.85rem + 2.5cqi, 1.5rem);
}
.product-card {
padding: clamp(0.75rem, 2.5cqi, 1.5rem);
}
Kombiniere das mit var() und clamp() aus früheren Modern-Toolkit-Lektionen. Container-Einheiten messen den Containment-Kontext der Abfrage — ideal für wiederverwendbare Widgets.
Container vs. Media — wer macht was?
📊 Container Queries vs. Media Queries
| Welche Frage stellst du? | Bevorzugen | Typisches Werkzeug |
|---|---|---|
| Wie breit ist der Browser-Viewport? | Seitenhülle, Navigation, mehrspaltige Seite | @media (min-width: …) |
| Wie breit ist dieser Eltern um eine Komponente? | Karten, Widgets, Embeds in ungleichen Slots | @container (min-width: …) nach container-type |
| Brauche ich beides? | Oft ja | MQ für die Seite; CQ für die Komponente im Slot |
Zwei Slots, eine Komponente
Eine kleine Skizze zeigt den Nutzen — zwei Container, eine Kartenklasse:
.page {
display: flex;
gap: 1rem;
align-items: start;
}
.rail {
container-type: inline-size;
container-name: rail;
width: 16rem;
}
.stage {
container-type: inline-size;
container-name: stage;
flex: 1;
min-width: 0;
}
/* Same .product-card class in both slots — @container rules above decide layout */
Du musst nicht .product-card--sidebar und .product-card--main nur wegen Slot-Breite splitten. Der Slot meldet seine Größe; die Karte hört zu.
Seiten-Media mit Komponenten-Containern paaren
Viewport-Queries für Seiten-Entscheidungen (Nav einklappen, Hülle einspaltig). Container Queries für Komponenten in jedem Slot, den die Seite vorgibt:
@media (max-width: 40rem) {
.page {
flex-direction: column;
}
.rail {
width: auto;
}
}
@container (min-width: 28rem) {
.product-card {
grid-template-columns: 10rem 1fr;
}
}
Auf dem schmalen Handy stapelt sich die Seite; auf dem breiten Desktop bleibt die Rail schmal, die Stage breit — nur Container Queries drücken diese Trennung sauber aus.
Selbst ausprobieren
container-type: inline-sizeum eine Karte legen; in DevTools den Containment-Kontext prüfen.@container (min-width: 24rem)schreiben: Karte von Stapel zu zwei Spalten.container-name: panelsetzen und mit@container panel (min-width: 30rem)zielen.- Überschrift mit
cqiskalieren und nur den Eltern verkleinern (nicht das Fenster). - Ein
@mediaan der Seitenhülle lassen; dieselbe Logik nicht in der Karte duplizieren.
Typische Fehler
@containerohnecontainer-typeam Vorfahren — nichts Sinnvolles zum Messen- Alle Media Queries durch Container Queries ersetzen — die Seitenhülle bleibt bei
@media - Drei Container verschachteln und raten, welche Breite zählt — benennen und gezielt ansprechen
- Viewport-Breakpoints (
48rem) blind in jedes Widget kopieren — am Slot feintunen, nicht am Gerätekatalog - Nesting (
&, verschachtelte Selektoren) mit Containment verwechseln — Nesting ordnet Selektoren; Container Queries messen Kästen
Kurzfassung
- Container Queries stylen nach Elterngröße, nicht nur Viewport
container-typesetzen (oftinline-size); optionalcontainer-name- Mit
@container (min-width: …)/@container name (…)Nachkommen umgestalten cqi/cqw, wenn Längen dem Container folgen sollen- Als Nächstes im Modern Toolkit: Feature Queries (
@supports) — Styles an Browser-Fähigkeit koppeln
🧠 Testen Sie Ihr Wissen
Testen Sie Ihr Wissen
Fordern Sie sich mit diesem interaktiven Quiz heraus und sehen Sie, wie gut Sie das Thema verstehen
📝 Anweisungen
- Lesen Sie jede Frage sorgfältig
- Wählen Sie die beste Antwort für jede Frage
- Sie können das Quiz so oft wiederholen, wie Sie möchten
- Ihr Fortschritt wird oben angezeigt