Container Queries

Container Queries erlauben es, Styles abhängig von der Grösse des Elternelements zu definieren – statt von der Grösse des Viewports wie bei Media Queries. Dadurch werden Komponenten unabhängig von ihrem Einsatzort und besser wiederverwendbar.


Eigenschaften

  • container-typeDefiniert ein Element als Container
  • @containerDefiniert Regeln, die auf die Grösse eines Containers reagieren
  • container-nameVergibt einen Namen für den Container
  • containerKurzschreibweise für container-name und container-type

Das Grundprinzip

Ein Element wird zuerst als Container definiert. Danach können Elemente im Inneren auf die Grösse dieses Containers reagieren.

@container sucht automatisch den nächstgelegenen Vorfahren, der mit container-type als Container definiert wurde.

.wrapper  ← container-type: inline-size
│
└── .card  ← wird in der @container-Regel gestaltet
<div class="wrapper">
  <div class="card">
    Inhalt der Karte
  </div>
</div>
.wrapper {
  container-type: inline-size;
  border: magenta 5px solid;
}

@container (min-width: 500px) {
  .card {
    background: yellowgreen;
  }
}

.wrapper ist der Container. .card liegt im Container und verändert ihre Darstellung, wenn der Container breit genug ist.

Wichtig: Die Container-Regel wird nicht auf den Container selbst angewendet, sondern auf Elemente innerhalb des Containers.

Demo – Box am Rand ziehen, um die Breite zu verändern:

Unter 500px: weisser Hintergrund.
Ab 500px: plum Hintergrund.
Die Karte reagiert auf ihren Container, nicht auf den Screen.

Container ist an der rechten Kante ziehbar.


container-type

Damit ein Element als Container funktioniert, braucht es container-type. Am häufigsten wird inline-size verwendet. Damit reagiert die Query auf die Breite des Containers.

  • inline-sizeReagiert auf die Breite des Containers
  • sizeReagiert auf Breite und Höhe
  • normalStandardwert – kein Grössenkontainer, aber Style Queries sind möglich

Praxis: In den meisten Fällen wird container-type: inline-size; verwendet. normal ist der Standardwert und erstellt keinen Grössencontainer. size wird nur benötigt, wenn die Query sowohl auf Breite als auch auf Höhe reagieren soll.

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

Hinweis: size braucht eine definierte Grösse in beide Richtungen. Für responsive Komponenten ist inline-size meistens die passende Wahl.


@container

@container funktioniert ähnlich wie @media. Der Unterschied: Die Bedingung bezieht sich nicht auf den Viewport, sondern auf den nächsten passenden Container.

.card {
    border: 3px solid orangered;
}

@container (min-width: 500px) {
    .card {
        border-color: green;
    }
}

Ab einer Containerbreite von 500px wechselt der Rahmen von .card von orangered zu green.


Media vs. Container Queries

Media Queries reagieren auf die Grösse des Viewports.
Container Queries reagieren auf die Grösse eines Containers.

<div class="cq-compare-box">
    <div class="cq-contact-card">
        <div class="cq-contact-info">
            <h4>Kim Keller ☺ </h4>
            <p>Frontend Designer</p>
        </div>

        <div class="cq-contact-links">
            <a href="#">Mail</a>
            <a href="#">Profil</a>
        </div>
    </div>
</div>
.cq-compare-box {
    container-type: inline-size;
}

.cq-contact-links a {
    display: block;
}

@container (min-width: 320px) {
    .cq-contact-links a {
        display: inline-block;
    }
}

Media Queries eignen sich für das Layout der ganzen Seite. Container Queries eignen sich für einzelne Komponenten, die an verschiedenen Orten eingesetzt werden.

Die gleiche Komponente kann in einem schmalen Container anders aussehen als in einem breiten Container. Der Viewport bleibt dabei gleich.

Media Query (Viewport)

Kim Keller ☺

Frontend Designer

Container Query (Container)

Kim Keller ☺

Frontend Designer

Gleicher HTML-Code, gleiche CSS-Klasse – der Container entscheidet das Layout.


container-name

In den meisten Fällen braucht ein Container keinen Namen. @container sucht automatisch den nächstgelegenen übergeordneten Container mit container-type.

Ein container-name wird nur benötigt, wenn mehrere Container verschachtelt sind und eine Regel gezielt auf einen bestimmten Container reagieren soll.

.layout {
  container-type: inline-size;
  container-name: layout;
}

@container layout (min-width: 350px) {
  .box {
    background: indigo;
  }
}

Praxis: Für die meisten Komponenten reicht der nächstgelegene Container aus. Ein container-name wird erst dann interessant, wenn gezielt ein bestimmter Container angesprochen werden soll.

layout ist kein Klassenname und keine ID. Es ist ein frei gewählter CSS-Name, der nur in container-name und @container layout verwendet wird.

Demo – Container mit dem Namen layout:

Unter 350px: deeppink Hintergrund. Über 350px: hotpink Hintergrund.

Container ist an der rechten Kante ziehbar.


Kurzschreibweise container

Die Eigenschaft container kombiniert container-name und container-type.

.layout {
  container: layout / inline-size;
}

Das ist die Kurzschreibweise für:

.layout {
  container-name: layout;
  container-type: inline-size;
}

Container Query Units

Container Query Units sind Einheiten, die sich auf die Grösse eines Containers beziehen. Sie funktionieren ähnlich wie vw und vh, aber nicht relativ zum Viewport, sondern relativ zum Container.

  • cqw1% der Container-Breite
  • cqh1% der Container-Höhe
  • cqi1% der Inline-Grösse
  • cqb1% der Block-Grösse
  • cqmin1% des kleineren Werts
  • cqmax1% des grösseren Werts
.wrapper {
  container-type: inline-size;
}

.title {
  font-size: 5cqi;
}

.wrapper ist der Container. .title liegt im Container und verwendet cqi. Die Einheit wird also auf ein Element im Container angewendet, nicht auf den Container selbst.

<div class="wrapper">
  <h2 class="title">Fluid Text</h2>
</div>

Demo – Schriftgrösse skaliert mit dem Container

Fluid Text

Container ist an der rechten Kante ziehbar.


Logische Operatoren

Wie bei Media Queries können Bedingungen kombiniert werden.

/* AND – beide Bedingungen müssen zutreffen */
@container (min-width: 400px) and (max-width: 800px) {
  .card {
    background: pink;
  }
}

/* OR – eine Bedingung reicht */
@container (max-width: 300px), (min-width: 600px) {
  .card {
    font-size: 0.8rem;
  }
}

/* NOT – Bedingung darf nicht zutreffen */
@container not (min-width: 400px) {
  .card {
    display: block;
  }
}

Kurz gesagt

  • Container Queries reagieren auf einen Container, nicht auf den Viewport
  • Das Elternelement braucht container-type
  • @container definiert die Regel für Elemente innerhalb des Containers
  • container-name ist optional und wird nur gebraucht, wenn ein Container gezielt angesprochen werden soll
  • container ist die Kurzschreibweise für container-name und container-type
  • Container Query Units wie cqi oder cqw beziehen sich auf die Grösse des Containers

Nurse Mehr zum Thema Responsive unter Media Queries und Flexbox.