Kickstage Logo
Default post hero

Component-first Responsive Design

Frontend
Valentin Topolovec
Valentin Topolovec
,
component first design - container queries in css

Seit inzwischen ungefähr 20 Jahren, seit „Responsive Design“ überhaupt ein Thema ist, wünschen sich Entwickler:innen Container Queries: „Lass meine Komponente auf den Platz reagieren, den sie bekommt – nicht auf den Viewport.“

Responsive Design bedeutete traditionell Media Queries: Du stylst Komponenten basierend auf der Viewport-Größe. Das funktioniert – bis dieselbe Komponente in unterschiedlichen Kontexten auftaucht (Sidebar, Grid, Modal, CMS-Block) und „Screen Width“ plötzlich das falsche Signal ist.
Container Queries lösen genau dieses Problem: Komponenten reagieren auf den Platz, den sie tatsächlich bekommen – nicht auf die Größe des Browserfensters.

Was Container Queries sind (und was nicht)

Media Queries: „Wenn der Viewport mindestens 1024px breit ist …“
Container Queries: „Wenn mein Parent-Container mindestens 480px breit ist …“

Dadurch werden Komponenten wirklich wiederverwendbar und unabhängig vom Layout.

Die 2 Dinge, die du brauchst

  1. Einen Container-Kontext auf einem Parent (meist container-type: inline-size;)
  2. Eine @container-Regel (optional mit einem benannten Container)
container-queries-vs-media-query


Deine erste Container Query (Mini-Beispiel)


  • Hier ist eine minimale Demo: Ein Container macht einen Absatz fett + orange, wenn der Container klein wird.
  • Hinweis: Ich verwende container-type: inline-size (denk „Breite“), weil container-type: size stärkeres Containment auslöst und ein Element kollabieren kann, wenn du es nicht explizit dimensionierst.

Das ist das Kernprinzip:

  • Deklariere einen abfragbaren Container mit container-type
  • Schreibe eine @container-Regel
  • Style die Kinder basierend auf dem Container, nicht auf dem Viewport

Praxisbeispiel 2: die „Smart Card“ mit Container-Breakpoints + cqi

Jetzt etwas Reales: eine Card-Komponente, die sich anpasst, wenn ihr Parent-Container größer wird:

  • Unter 480px: gestapelt (Bild oben)
  • Ab 480px: Split-Layout (Bild links, Content rechts)
  • Ab 750px: schönerer Hintergrund, Titel-Farbe ändert sich, Typografie skaliert, Button-Stil ändert sich

Das ist eine component-first responsive Card, angetrieben von Container Queries.

Die wichtige Idee: Nichts in dieser Komponente hängt vom Viewport ab. Du kannst die Card in eine Sidebar setzen, in eine Grid-Spalte, in ein Modal oder in einen CMS-Block mit begrenzter Breite – und sie verhält sich trotzdem korrekt, weil sie auf die Breite ihres Parent-Containers reagiert.

Um das leichter verständlich zu machen, ist der Parent-Wrapper außerdem resizable (zieh die Ecke unten rechts). So kannst du unterschiedliche Layout-Kontexte „simulieren“, ohne die Browserfenstergröße zu ändern.

Schritt 1: die Container-Grenze definieren

Die Container Queries funktionieren nur, weil der Wrapper als Container deklariert ist.

1.resizable-wrapper {
2 container-type: inline-size;
3 container-name: card-container;
4 resize: horizontal;
5 overflow: hidden;
6}

Warum container-type: inline-size?

Es sagt dem Browser: „Du darfst Container Queries basierend auf der Inline-Size dieses Elements ausführen.“
In den meisten Layouts entspricht inline-size praktisch der Breite.

Für UI-Komponenten ist das die sicherste und pragmatischste Option, weil es einige der stärkeren Containment-Effekte von container-type: size vermeidet.

Warum ein container-name?

Ein benannter Container macht Queries expliziter und leichter wartbar.

1@container card-container (min-width: 480px) { ... }

Schritt 2: den Container abfragen – nicht den Screen

Statt @media nutzen wir @container. Die Card hat zwei Container-Breakpoints:

Breakpoint 1: bei 480px

1@container card-container (min-width: 480px) {
2 .smart-card {
3 flex-direction: row;
4 }
5}

Was sich ändert:

  • Layout wechselt von gestapelt (Bild oben) zu Split (Bild links, Content rechts)
  • Das Bild nimmt einen festen Anteil der Breite ein
  • Die Bildhöhe wechselt von fixen 200px zu height: 100%, damit es sauber die Spalte füllt

Das ist der klassische „responsive card“-Layoutwechsel – aber ausgelöst durch verfügbaren Container-Platz, nicht durch den Viewport.

Breakpoint 2: bei 750px

1@container card-container (min-width: 750px) {
2 .card-title {
3 font-size: 5cqi;
4 color: var(--brand-orange);
5 }
6}

Was sich ändert:

  • Die Card bekommt einen subtilen Background-Gradient (fühlt sich mehr nach „Desktop“ an)
  • Typografie wird größer (z. B. .card-desc)
  • Button-Styling wird prominenter
  • Titel-Farbe ändert sich passend zum Branding

Dieser Breakpoint ist ein gutes Beispiel für etwas, das mit Media Queries oft falsch aussieht: Wenn die Komponente in einer schmalen Spalte auf einem großen Screen steckt, willst du kein „Desktop Styling“ nur weil der Viewport groß ist. Du willst es nur, wenn die Komponente genug Platz hat.

Schritt 3: cqi Units – responsive Typografie basierend auf dem Container

Diese Demo nutzt außerdem Container Query Units:

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

cqi bedeutet: 1% der Inline-Size des Containers.
Wenn der Container wächst, wächst die Überschrift smooth mit – sogar zwischen Breakpoints. Das ist ein schönes Upgrade gegenüber den üblichen „Sprüngen“ durch fixe Font Sizes an Breakpoints.

Am größeren Breakpoint überschreiben wir es dann bewusst.

1@container card-container (min-width: 750px) {
2 .card-title {
3 font-size: 5cqi;
4 }
5}


Container Query Length Units (cq*)

Container Query Length Units lassen dich Größen relativ zum nächsten Query-Container setzen – statt relativ zum Viewport. Sie sind das containerbasierte Pendant zu vw/vh und damit perfekt für fließende Typografie, Spacing und Layout-Details in wiederverwendbaren Komponenten.

Wenn es keinen geeigneten Container in der Ancestor-Chain gibt, fallen diese Units auf die passenden small viewport units der jeweiligen Achse zurück.

Die Units:

  • cqw — 1% der Container-Breite
  • cqh — 1% der Container-Höhe
  • cqi — 1% der Container-Inline-Size (meist Breite)
  • cqb — 1% der Container-Block-Size (meist Höhe)
  • cqmin — das kleinere von cqi und cqb
  • cqmax — das größere von cqi und cqb

Faustregel: Greif zuerst zu cqi (die meisten Komponenten skalieren über Breite) und nutze cqmin/cqmax, wenn du willst, dass die Skalierung die kleinere oder größere Dimension respektiert.

Warum das in echten Projekten zählt

Die „Smart Card“ ist ein Beispiel für praktisch jede reale Komponente:

  • Blog Cards
  • Product Tiles
  • CMS „Feature Blocks“
  • Pricing Cards
  • Author Blocks
  • Dashboard Widgets

Mit Media Queries können diese Komponenten kaputtgehen, sobald du sie in ein anderes Layout verschiebst. Mit Container Queries wird die Komponente portabel: Sie passt sich dem Platz an, den sie tatsächlich bekommt – nicht Annahmen über die Seite.

Das ist der echte Gewinn: Container Queries verschieben Responsive Design von page-first zu component-first.

Tailwind-Beispiel

Du kannst Container Queries in Tailwind genauso nutzen wie responsive Utilities – nur dass die Breakpoints auf der Größe eines Parent-Containers basieren, nicht auf dem Viewport. In Tailwind v4 sind Container Queries built-in (kein Plugin nötig).

Diese Demo nutzt Container Queries für das Grid-Layout und für das Innenleben jeder Card – sodass das Ganze auf den Platz des Parent-Containers reagiert, nicht auf den Viewport.

Im Beispiel unten:

  • Das Grid ändert die Spaltenzahl basierend auf der Container-Breite (@sm, @lg, @2xl) und verhält sich dadurch korrekt in Sidebar, CMS-Block oder constrained Layout.
  • Jede Card ist ihr eigener benannter Container (@container/card) und wechselt von stacked → split bei 480px und bekommt „Desktop Polish“ bei 750px – basierend auf verfügbarem Card-Platz, nicht auf Seitenbreite.

Hinweis für ältere Tailwind-Versionen

Wenn du Tailwind v3.2+ nutzt (und noch nicht v4), bekommst du Container Queries über das offizielle Plugin @tailwindcss/container-queries. Ab Tailwind v4 ist es integriert und das Plugin ist nicht erforderlich.

Browser Support

Container Queries sind in modernen Browsern gut unterstützt – für die meisten Production Sites kannst du sie heute sicher einsetzen.

Fazit

Mit Viewport-Breakpoints koppeln sich Komponenten oft an Layout-Annahmen: „Das ist eine Sidebar-Card“, „das ist eine Homepage-Card“, „das ist eine Modal-Card“. Mit der Zeit sammelst du Varianten, Overrides und One-off Breakpoints, die nur in einer ganz bestimmten Seitenstruktur Sinn ergeben.

Container Queries drehen das um. Eine Komponente kann ihre eigenen Regeln definieren, wie sie sich bei unterschiedlichen Größen verhält – und diese Regeln bleiben gültig, egal wo du sie platzierst: Grids, Sidebars, Dashboard Widgets, CMS-Blocks oder Embedded Layouts. Das ist ein großer Gewinn: Komponenten werden portabler und wiederverwendbarer, weil sie sich an den tatsächlich verfügbaren Platz anpassen.

Wenn du das nächste Mal Cards, Tiles oder Widgets baust, die in mehreren Kontexten funktionieren müssen, probier das:

  • Mach die Komponente bei der kleinsten Größe richtig gut
  • Füge einen Layout-Breakpoint hinzu (z. B. stacked → split)
  • Poliere alle weiteren Breakpoints (Typografie + Spacing + Layout-Details)
  • Nutze Container-Units wie cqi für smoothes Scaling, wo es sinnvoll ist (oder andere, wenn nötig)

Das reicht meistens, um den „Wow“-Effekt von Container Queries mitzunehmen – ohne deine UI in Breakpoint-Suppe zu verwandeln.

Praktisch verbessert das oft sofort drei Dinge:

Weniger fragile Breakpoints

Du hörst auf, „Geräte zu raten“, und reagierst stattdessen auf echte Layout-Constraints. Das ist besonders wertvoll in modernen UIs, wo dieselbe Komponente in 3–10 verschiedenen Kontexten auftauchen kann.

Sauberere Design-Systeme

Komponenten werden in sich geschlossen. Teams können neue Layouts shippen, ohne Component-CSS neu zu schreiben, und Designer:innen können sich auf konsistentes Verhalten im gesamten System verlassen. Das passt gut zur Idee „responsive components“, die seit Jahren als Lösung gegen viewport-getriebene Kopplung diskutiert wird.

Bessere Progressive Enhancement

Es ist einfacher, ein solides Default (gestapelte Card) zu bauen und Verbesserungen zu layern, wenn Platz da ist. Das passt gut dazu, dass Container Queries Media Queries ergänzen, statt sie komplett zu ersetzen.

Wenn du mit Tailwind arbeitest, fühlen sich Container Queries besonders natürlich an: Du bekommst denselben schnellen Iterations-Loop wie bei responsive Utilities – aber triffst deine Entscheidungen basierend auf dem Container. Dass Tailwind v4 das first-class macht (ohne Plugin), ist ein gutes Signal: Container Queries sind von „cooles neues CSS“ zu einem praktischen Tool geworden, das du täglich verwenden kannst.

Das passt außerdem super zu modernen Component-Stacks wie shadcn/ui und Radix Primitives. Radix gibt dir ungestylte, accessible Building Blocks, und shadcn/ui liefert diese Patterns als Copy-Paste-Components, die dir komplett gehören – also genau dafür gedacht, in vielen unterschiedlichen Layouts wiederverwendet zu werden. Container Queries machen die Story komplett: Derselbe Dialog, dieselbe Card oder derselbe Sidebar-Widget kann sich an den Platz anpassen, den er bekommt – nicht an die Seite, in der er zufällig steckt.

Oder anders gesagt: Radix liefert die Struktur, shadcn liefert production-ready Patterns, Tailwind liefert Styling-Speed – und Container Queries liefern das fehlende Teil: Layout-Unabhängigkeit. Container Queries sind nicht einfach „schönere Media Queries“ – sie verlagern den Ort, an dem Responsiveness lebt.



Lassen Sie uns Ihr Projekt realisieren

Sie suchen technische Expertise für die Planung und Umsetzung digitaler Vorhaben, damit Sie sich auf Ihre Kernaufgaben konzentrieren können? Wir unterstützen Sie dabei. Besuchen Sie uns für ein persönliches Gespräch oder kontaktieren Sie uns direkt.

Kontakt

Büro Zagreb

Radnička cesta 47, 10000, Zagreb, Croatia

Social Media

Pascal Ehlert

Pascal Ehlert

Business Development