← Zurück

CSS Container Queries

Responsive Design basierend auf CONTAINER, nicht Viewport.

❌ Das Problem mit Media Queries

Media Queries fragen die VIEWPORT-Größe — aber Komponenten wissen nicht, wo sie im Layout sind.

Eine Card in der Sidebar vs. im Hauptbereich:

→ Gleiche Viewport-Größe

→ Unterschiedlicher verfügbarer Platz

→ Media Queries können das nicht unterscheiden!

✅ Die Lösung: Container Queries

Container Queries fragen die CONTAINER-Größe — Komponenten passen sich ihrem verfügbaren Platz an.

.card-wrapper {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .card {
    flex-direction: row;
  }
}

⚠️ Die Goldene Regel

"You cannot change what you measure."

Wenn du die Container-Breite abfragst, kannst du nicht die Breite des Containers ändern. Nur die Styles der KINDER können geändert werden.

❌ FALSCH: Container-Styles in @container ändern

✅ RICHTIG: Kinder-Styles in @container ändern

Warum es 20 Jahre "unmöglich" war

Das Endlosschleifen-Problem:

1 Container ist 100px breit
2 @container (max-width: 150px) matched → font-size erhöht
3 Größerer Text → Container wächst auf 200px
4 Bedingung nicht mehr erfüllt → font-size zurück
5 Container schrumpft → Bedingung wieder erfüllt...
ENDLOSSCHLEIFE!

Lösung: Containment API — Container reagiert NICHT auf seinen Inhalt. Die Größe ist "eingesperrt" (contained).

container-type verstehen

inline-size

Container-Breite kann abgefragt werden. Höhe wächst normal mit Inhalt.

✅ Das ist der Sweet Spot für 90% der Fälle!

size

Breite UND Höhe können abgefragt werden. Aber: Höhe muss explizit gesetzt sein!

⚠️ Seltener gebraucht, da Höhe meist dynamisch sein soll

normal

Default. Nur Style Queries möglich, keine Size Queries.

Alle Elemente sind automatisch Style Container

Basic Syntax

/* 1. Container definieren */
.card-wrapper {
  container-type: inline-size;
  container-name: card;  /* optional, für spezifisches Targeting */
}

/* Shorthand */
.card-wrapper {
  container: card / inline-size;
}

/* 2. Container Query schreiben */
@container card (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 1fr 2fr;
  }
}

/* Ohne Namen — matched JEDEN Container */
@container (min-width: 400px) {
  .card {
    flex-direction: row;
  }
}

Container Query Units

cqw

1% der Container-Breite

cqh

1% der Container-Höhe

cqi

1% der inline-size (= Breite)

cqb

1% der block-size (= Höhe)

cqmin

Kleinerer von cqi/cqb

cqmax

Größerer von cqi/cqb

Beispiel: Fluid Typography basierend auf Container

.card-title {
  font-size: clamp(1rem, 5cqi, 2rem);
}

Schriftgröße skaliert mit Container-Breite, nicht Viewport!

Range Syntax (Modern)

width > 400px

Breiter als 400px

width >= 400px

400px oder breiter

width < 400px

Schmaler als 400px

300px < width < 600px

Zwischen 300px und 600px

Wann Container Queries verwenden?

Wiederverwendbare Komponenten

Cards, Buttons, Navigation — überall nutzbar

Sidebar vs. Hauptinhalt

Gleiche Komponente, unterschiedlicher Platz

Grid Layouts

Komponenten die in verschiedenen Grid-Zellen leben

Media Queries weiterhin für...

Globale Layouts, Navigation, Viewport-bezogene Änderungen

Style Queries (Experimentell)

Fragen CSS-Werte statt Größe ab — aktuell nur Custom Properties:

/* Kein container-type nötig! Alle Elemente sind Style Container */

.card {
  --theme: dark;
}

@container style(--theme: dark) {
  .card-content {
    background: #000;
    color: #fff;
  }
}

⚠️ Browser Support noch begrenzt — nur mit Feature Flag

Browser Support

Size Queries: ~93% ✅

  • Chrome 105+ (August 2022)
  • Safari 16+ (September 2022)
  • Firefox 110+ (February 2023)

✅ Was ich WIRKLICH verstanden habe