Lädt...

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:

Turn a rail into a size container

css
.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 reacts to its parent width

css
.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:

Target a named containment context

css
@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):

Type that tracks the container

css
.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:

Sidebar rail and main stage share one card

css
.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:

Viewport for the page, container for the card

css
@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

  1. container-type: inline-size um eine Karte legen; in DevTools den Containment-Kontext prüfen.
  2. @container (min-width: 24rem) schreiben: Karte von Stapel zu zwei Spalten.
  3. container-name: panel setzen und mit @container panel (min-width: 30rem) zielen.
  4. Überschrift mit cqi skalieren und nur den Eltern verkleinern (nicht das Fenster).
  5. Ein @media an der Seitenhülle lassen; dieselbe Logik nicht in der Karte duplizieren.

Typische Fehler

  • @container ohne container-type am 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-type setzen (oft inline-size); optional container-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

Bereit zum Start

Testen Sie Ihr Wissen

Fordern Sie sich mit diesem interaktiven Quiz heraus und sehen Sie, wie gut Sie das Thema verstehen

❓
6
Fragen
🎯
70%
Zum Bestehen
♾️
∞
Zeit
🔄
∞
Versuche

📝 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