Lerne Coding
Container Queries: In Komponenten denken!
12.08.2023

Responsive Design 2.0: Container Queries

Inhaltsverzeichnis
[[TABLE OF CONTENTS]]
access_timeGeschätzte Lesezeit ca. Minuten

Container Queries sind eine noch relative neue Möglichkeit beim Stylen von Responsive Webseiten vorzugehen. Bei Media Queries sind wir nach der Mediengröße vorgegangen, um ein entsprechendes Styling für verschiedene Größen zu erstellen. Die größte Problematik dabei war immer, wenn wir eine Box gestaltet haben, die wir auf verschiedenen Größen benötigt haben, auch wenn diese vom Styling ähnlich war, mussten wir immer eine komplette Seite Responsive gestalten. Haben wir die Komponente (die Box) an einer anderen Stellen verwendet, mussten wir wieder einiges neu gestalten, genauer gesagt die CSS Regeln neu definieren. Mit Systemen wie Vue.js, Svelt, Angular 2 und React wurde immer mehr in sogenannten Komponenten gedacht und immer weniger in kompletten Seiten, umso schwieriger wurde es globale Styles für eine Seite zu definieren. All diese Frameworks haben sogenannte Scoped Styles implementiert, um das Styling von Komponenten zu vereinfachen.

Daraus resultierend war eigentlich immer der nächste sinvolle Schritt eine einfachen weg bereitzustellen Styles responsiv innerhalb einer Komponente zu definieren. Wir haben etwa eine Box für ein Produkt, um diese darzustellen. In einem Szenario wollen wir 3 untereinander in der Sidebar von 200px breite darstellen und in einem anderen 3 Stück nebeneinander auf 1200px breite. Dieser Platz kann sehr unterschiedlich genutzt werden. Um diese nun effizent zu erledigen wäre es am sinnvollsten die Komponente in sich geschlossen Responsive zu gestalten, um sie immer wieder verwenden zu können. Ohne jeweilige Anpassungen an die Geräte größe machen zu müssen, allein dadurch das wir Einzelende Komponenten z. B. von einer Breite von 200px bis 1200px Breite gestalteten. Wissen wir immer, wenn wir sie in einer Größe dazwischen verwenden, dass sie funktionieren wird, ohne sie noch mal in verschiedenen Gerätebreiten durchtesten zu müssen – wie bei den Media Queries.

Etwa der folgende Aufbau besteht aus denselben Klassen und Elementen und nur durch den Container Query wurde das Design verändert.

Beispiel für ein Container Query
Beispiel für ein Container Query

Durch dieses kleinteilige Denken in Komponenten, die in sich geschlossen funktionieren, können größere Bereiche einer Webseite schnell zusammengesetzt werden. Ich denke, es sollte hier aber auch etwas differenziert werden, ob man eine kleine Portfolioseite umsetzt oder ein Shop System mit 1000 unterschiedlichen Komponenten, die häufig wieder verwendet werden. Die Portfoliowebseite wird in der Regel einmal erstellt und danach nicht häufig wieder verändert im größeren Stile. Der Onlineshop wird so viele Änderungen erfahren und kann so viele verschiedenen Seiten Templates haben, dass es einfacher ist, mit Container Queries zu arbeiten.

Daraus resultierend solltest du gut nachdenken, ob es für dich wirklich das richtig ist. Denn mit Container Queries bringst du sicherlich eine komplexere Ebene noch einmal in deine Webseite/Anwendung.

CSS Container Queries (Size) Verfügbarkeit Weltweit: 91.07%

Size queries in Container Queries provide a way to query the size of a container, and conditionally apply CSS to the content of that container.

Internet Explorer nein
Microsoft Edge 106 +
Firefox 110 +
Google Chrome 106 +
Safari 16.0 +
Opera 94 +
iOS Safari 16.0 +
Opera Mini nein
Android Webview 123 +
Android Chrome 123 +
Android Firefox 124 +
Samsung Internet 20 +
Daten abgerufen von https:/­/­caniuse.com/­css-container-queries

Der Browser Support ist schon recht gut, dennoch kann ich empfehlen, wenn ihr noch ältere Browser von vor 2–3 Jahren unterstützten wollt und auch einige Mobile Browser unterstützen Container Queries noch nicht 100 % kann es sich lohnen, ein sogenannten Polyfill einzusetzen.

Github LogoGoogleChromeLabs/container-query-polyfill
1.112 13 50

A polyfill for CSS Container Queries

Was ist ein Polyfill?

Ein Polyfill ist in der Regel ein JavaScript-Code der moderne Funktionalitäten in älteren Browsern „nachfüllt“. Damit diese mit den aktuellen Standards mithalten können. In der Regel prüft ein Polyfill immer zuerst, ob die native Funktion verfügbar ist, falls nicht, wird diese durch eine JavaScript-Code im Browser nachgebildet.

Anwendung von Container Queries

Die größten Unterschiede zwischen Media Queries und Container Queries ergeben sich daraus, dass Container Queries Elementen Größen bezogen sind und Media Queries sich auf den Viewport beziehen. Bei Container Queries müssen wir also definieren, welches Element unser Container ist. Dafür haben wir zwei Eigenschaften als Möglichkeit zur Definition container-type

und container-name wobei wir den Container Namen nur dann benötigen, wenn wir mehren, Container verschachtelt nutzen wollen und ein inneres Element soll sich nicht auf den nächsten Elterncontainer beziehen, sondern auf einen, der weiter außen liegt.

container-type: inline-size
container-name: header

Zusätzlich gibt es noch den Shorthand der die Type Property mit der Namen Property kombiniert.

container: header / inline-size

Die folgenden Eigenschaften gibt es für den container-type :

  • size: Der Query basiert auf den inline und block Dimensionen des Containers.
  • inline-size: Der Query basiert nur auf den inline Dimensionen des Containers.
  • normal: Das Element wird nicht als Query-Container für Größenabfragen verwendet, bleibt aber ein Query-Container für Style-Queries.

In der Regel verwendet man immer den inline-size Typen, da der size Type nicht die höhe des inneren Elements verwendet.

Der HTML-Aufbau für einen Container

Der Aufbau für einen Container könnte zum Beispiel wie folgt aussehen, wir haben ein äußerer Container, der die Größe vorgibt. Und dort drinnen haben wir die Eigenschaften unseres Teasers. In diesem Fall hat die Class Container nur die inline-size Eigenschaft, in den meisten Fällen kommt man mit einer globalen Klasse für den Container aus. Und der jeweilige Teaser wird dann nur noch innerhalb des Container Queries gestylte.

<div class="container">
  <div class="product">
          <img src="https://hellocoding.de/assets/placeholder/pic-8.jpg">
          <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
     </div>
</div>

Der Container Query

Der Container Query verhält sich komplett ähnlich wie der Media Query, mit dem Unterschied das noch ein Name angegeben werden kann, ist aber nur notwendig wenn ihr auch die Eigenschaft container-name verwendet habt. Ansonst gibt es keine größeren Veränderungen. In dem Beispiel habe ich noch die neue Syntax für die Größe vergleich verwendet. Alternative kannst du auch mit min-width: 700px arbeiten.

@container platzhalterName (width > 700px) {
  .product{
    background: #2f2f2f;
    flex-direction: row;
  }

  .product p{
    color: white;
    font-size: 18px;
    line-height: 1.5em;
    padding: 0px;
    margin-right: 16px;
  }

  .product img{
    display: block;
    height: 100%;
    width: 300px;
  }
}

Container Size – Größen, Eigenschaften

Zusätzlich gibt es noch neue Größen Eigenschaften für Container, allerdings kann ich euch nicht empfehlen diese bereits zu verwenden, da der Support auch mit Polyfill noch nicht gut gewährleistet ist zum aktuellen Zeitpunkt (August, 2023).

Thema der Tabelle "Container Size"
Abkürzung Beschreibung
cqw 1% der Breite eines Abfragecontainers
cqh 1% der Höhe eines Abfragecontainers
cqi 1% der Inline-Größe eines Abfragecontainers
cqb 1% der Block-Größe eines Abfragecontainers
cqmin Der kleinere Wert von entweder cqi oder cqb
cqmax Der größere Wert von entweder cqi oder cqb

Beispiel

html{
  background: #1b1f21;
}

.example-code{
  box-sizing: border-box;
  padding: 32px;
  max-width: 1920px;
  margin: 0 auto;
}

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

.grid{
  display: grid;
  grid-template-columns: repeat( 12, 1fr );
  gap: 32px;
}

.grid-span-8{
  grid-column: 4/13
}

.grid-span-4{
  grid-column: 1/4
}

.product{
  display: flex;
  gap: 16px;
  border-radius: 20px;
  background: #efefef;
  overflow: hidden;
  flex-direction: column;
}

.product img{
  display: block;
  height: 400px;
  width: 100%;
  object-fit: cover;
}

.product p{
  font-family: barlow;
  font-size: 16px;
  padding: 16px;
}

@container (width > 700px) {
  .product{
    background: #2f2f2f;
    flex-direction: row;
  }
  
  .product p{
    color: white;
    font-size: 18px;
    line-height: 1.5em;
    padding: 0px;
    margin-right: 16px;
  }
  
  .product img{
    display: block;
    height: 100%;
    width: 300px;
  }
}
<div class="grid">
   <div class="grid-span-4 container">
      <div class="product">
       <img src="https://hellocoding.de/assets/placeholder/pic-8.jpg" class="noLazy">
      <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
     </div>
   </div>
   <div class="grid-span-8 container">
      <div class="product">
       <img src="https://hellocoding.de/assets/placeholder/pic-8.jpg" class="noLazy">
      <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
     </div>
   </div>
</div>

Fazit

Für kleinere Projekte wird es sich wahrscheinlich zukünftig noch nicht lohnen, mit Container Queries zu arbeiten, für größere Projekte sehe ich in Container Queries ein großes Potenzial, um die Arbeit zu erleichtern. Gerade im Zusammenhang mit JS Frameworks wie Vue.js, Svelt, Angular 2 und React denke ich, dass Container Queries ein großes Potenzial haben.

Natürlich darf man auch die Nachteile nicht aus den Augen verlieren, Entwickler, die bereits viel mit Media Queries arbeiten, kann die Umgewöhnung und das Denken in Komponenten schwerfallen. Das Wichtigste ist, dranzubleiben und immer wieder daran zu arbeiten, das Konzept entsprechend umzusetzen und dafür braucht es auch kein JS Framework.

Nicht immer ist der Container Query die Lösung und es sollte auch dran gedacht werden, dass die Komplexität steigt und auch mehr Ressourcen im Browser für das Rendering benötigt werden als bei Media Queries. In den meisten modernen Browsern sollte das sich aber im Maßen halten und keine nennenswerte Auswirkung haben.

Bildquelle - Vielen Dank an die Ersteller:innen für dieses Bild
Kommentare zum Artikel
Lars (LGK) schreibt ... Kommentar vom 14.08.2023
Ich freue mich über das Feature!

Für spezielle Fälle ein sehr nützliches Feature. Ich brauchte das vor ein paar Jahren für eine Detail-Ansicht an der Seite. Die Komponenten darin sind mit dem Grid-System von Bootstrap angeordnet. Das Problem war, dass die Anordnung darin natürlich nur darauf gehört hat, wenn sich die Fenstergröße und nicht der Detail-Bereich geändert hat. Hatte das mit https://github.com/marcj/css-element-queries gelöst, eine Lösung mit JavaScript. Mit diesem Code habe ich das Bootstrap Grid-System auf Element Queries umgemünzt: https://gist.github.com/lgk-bsw/ee32fad9535b60ad0f0fb2bcd53411e1 (vielleicht für den ein oder anderen nützlich). Jetzt wo es Container Queries gibt, will ich das mal darauf umstellen. ^^

Antworten
Lars (LGK)
Antwort von Felix Schürmeyer Kommentar vom 14.08.2023
Re: Ich freue mich über das Feature!

Danke für das Feedback.

Tatsächlich hatte ich so einen ähnlichen Use Case auch schon vor geraumer Zeit - dort waren Container Queries für mich auch noch keine Option. Weshalb ich dort etwas Ähnliches wie diese "Element Queries" selber geschrieben habe.

So etwas nun komplett nativ zu haben im Browser ist echt wunderbar. Mein persönlicher Gedanke, wie du dem Artikel auch entnehmen kannst, geht ja noch viel weitere ganze Webseiten mehr/oder weniger darüber zu lösen. Ich setze dieses Konzept momentan mit Nuxt, Tailwind und Container Queries Support momentan für das Redesign von HelloCoding.de um.

Für Tailwind gibt es dort eine passende Erweiterung: https://github.com/tailwindlabs/tailwindcss-container-queries

Felix Schürmeyer
Kommentar schreiben

Vom Autor Empfohlen
close