Containerabfragen landen in stabilen Browsern, während Polyfill ein großes Update erhält.

Containerabfragen sind da!

Es gibt gute Neuigkeiten: Eine der am häufigsten angefragten Entwicklerfunktionen wird jetzt in Webbrowsern eingeführt. Ab Chromium 105 und Safari 16 können Sie in diesen Browsern größenbasierte Containerabfragen erstellen und Containerabfrageeinheitswerte verwenden. Damit die Verwendung von größenbasierten Containerabfragen und cq-Einheiten noch einfacher wird, hat das Aurora-Team von Chrome hart daran gearbeitet, den Container Query Polyfill zu aktualisieren, um mehr Browser und Anwendungsfälle zu unterstützen. So können Sie diese leistungsstarke Funktion jetzt mit gutem Gewissen verwenden.

Was sind Containerabfragen?

Containerabfragen sind eine CSS-Funktion, mit der Sie eine Stillogik schreiben können, die auf Elemente eines übergeordneten Elements ausgerichtet ist, um die entsprechenden untergeordneten Elemente zu gestalten. Sie können ein wirklich komponentenbasiertes responsives Design erstellen, indem Sie die Größe eines übergeordneten Elements abfragen. Das sind viel detailliertere und nützlichere Informationen als Media-Queries, die nur Größeninformationen zum Darstellungsbereich liefern.

ALT_TEXT_HERE

Mit Containerabfragen können Sie wiederverwendbare Komponenten schreiben, die je nachdem, wo sie sich auf der Seite befinden, unterschiedlich aussehen können. Dadurch sind sie viel robuster und reaktionsschneller auf verschiedenen Seiten und Vorlagen.

Containerabfragen verwenden

Angenommen, Sie haben HTML:

<!-- card parent -->
<div class=”card-parent”>
  <div class=”card>
     <!-- card contents -->
      …
  </div>
</div>

Wenn Sie eine Containerabfrage verwenden möchten, müssen Sie zuerst die Begrenzung für das übergeordnete Element festlegen, das Sie erfassen möchten. Legen Sie dazu das Attribut container-type fest oder verwenden Sie das Kürzel container, um den Containertyp und den Containernamen gleichzeitig festzulegen.

.card-parent {
  /* query the inline-direction size of this parent */
  container-type: inline-size;
}

Jetzt können Sie mit der @container-Regel Stile basierend auf dem übergeordneten Element festlegen. Für ein Design wie das Bild oben, bei dem eine Karte von einer Spalte in zwei Spalten übergehen kann, schreiben Sie beispielsweise Folgendes:

@container (min-width: 300px) {
  .card {
    /* styles to apply when the card container (.card-parent in this case) is >= 300px */
    /* I.e. shift from 1-column to 2-column layout: */
    grid-template-columns: 1fr 1fr;
  }
}

Geben Sie dem Container des übergeordneten Elements einen Namen, um es übersichtlicher und expliziter zu gestalten:

.card-parent {
  container-type: inline-size;
  /* set name here, or write this in one line using the container shorthand */
  container-name: card-container;
}

Schreiben Sie den vorherigen Code dann so um:

@container card-container (min-width: 300px) {
  .card {
    grid-template-columns: 1fr 1fr;
  }
}

Container-Abfrageeinheiten

Containerabfragen lassen sich noch nützlicher machen, wenn Sie auch containerbasierte Einheitswerte verwenden. In der folgenden Tabelle sind die möglichen Werte für die Containereinheit und ihre Zuordnung zur Größe eines Containers aufgeführt:

Einheitrelativ zu
cqw1 % der Breite eines Abfragecontainers
cqh1 % der Höhe eines Abfragecontainers
cqi1 % der Inline-Größe eines Abfragecontainers
cqb1 % der Blockgröße eines Abfragecontainers
cqminDer kleinere Wert von cqi oder cqb
cqmaxDer größere Wert von cqi oder cqb

Ein Beispiel für die Verwendung containerbasierter Einheiten ist die responsive Typografie. Mit den auf dem Darstellungsbereich basierenden Einheiten (z. B. vh, vb, vw und vi) kann die Größe eines beliebigen Elements auf dem Bildschirm angepasst werden.

.card h2 {
  font-size: 15cqi;
}

Mit diesem Code wird die Schriftgröße auf 15% der Inline-Größe des Containers angepasst, d. h., sie wird mit zunehmender Inline-Größe (Breite) größer oder kleiner, wenn sie abnimmt. Mit der Funktion clamp() können Sie Ihrer Typografie ein Mindest- und Höchstmaß festlegen und sie dann basierend auf der Containergröße responsive anpassen:

.card h2 {
  font-size: clamp(1.5rem, 15cqi, 3rem);
}

Die Überschrift wird jetzt nie größer als 3rem oder kleiner als .5rem sein, nimmt aber zwischen diesen Werten 15 % der Inline-Größe des Containers ein.

In dieser Demo gehen wir noch einen Schritt weiter und aktualisieren die breiteren Karten, damit sie in einer Ansicht mit zwei Spalten kleiner erscheinen.

Polyfill für Containerabfragen

Da Containerabfragen eine so leistungsstarke Funktion sind, möchten wir, dass Sie sie problemlos in Ihre Projekte einbinden können. Der Browsersupport spielt dabei eine wichtige Rolle. Aus diesem Grund haben wir Verbesserungen am Container Query Polyfill vorgenommen. Diese Polyfill wird allgemein unterstützt in:

  • Firefox 69 und höher
  • Chrome (ab Version 79)
  • Edge 79 und höher
  • Safari 13.4 und höher

Sie hat nach der Komprimierung eine Größe von weniger als 9 KB und verwendet ResizeObserver mit MutationObserver, um die vollständige @container-Abfragesyntax zu unterstützen, die derzeit in stabilen Browsern verfügbar ist:

  • Diskrete Abfragen (width: 300px und min-width: 300px)
  • Bereichsanfragen (200px < width < 400px und width < 400px)
  • Einheiten für die relative Länge des Containers (cqw, cqh, cqi, cqb, cqmin und cqmax) in Eigenschaften und Frames

Polyfill für Containerabfragen verwenden

Wenn Sie die Polyfill verwenden möchten, fügen Sie dem Head-Element Ihres Dokuments dieses Script-Tag hinzu:

<script type="module">
  if (!("container" in document.documentElement.style)) {
    import("https://unpkg.com/container-query-polyfill@^0.2.0");
  }
</script>

Sie können auch einen Dienst verwenden, um die polyfill bedingt basierend auf User-Agent bereitzustellen, oder sie selbst an Ihrem eigenen Ursprung hosten.

Für eine optimale Nutzererfahrung sollten Sie die polyfill anfangs nur für Inhalte verwenden, die nicht im sichtbaren Bereich sind, und sie mit @supports-Abfragen vorübergehend durch einen Ladebalken ersetzen, bis die polyfill bereit ist, sie anzuzeigen:

@supports not (container-type: inline-size) {
  .container,
  footer {
    display: none;
  }

  .loader {
    display: flex;
  }
}

In ausreichend schnellen Netzwerken und auf Geräten, die Containerabfragen nativ unterstützen, wird dieser Ladebalken nie angezeigt.

Neue Polyfill-Funktionen

Der aktualisierte Polyfill unterstützt:

  • Verschachtelte @container-Regeln
  • Das Verschachteln von @container-Regeln in @supports- und @media-Abfragen und umgekehrt wird unterstützt.
  • Bedingte CSS-Anweisungen wie @supports (container-type: inline-size) werden erst nach dem Laden der Polyfill-Funktion ausgeführt.
  • Vollständige Unterstützung der CSS-Syntax (es gibt keine Probleme mehr, Kommentare an beliebiger Stelle einzufügen, sofern sie syntaktisch korrekt sind).
  • Vertikale Schreibmodi (über „writing-mode“).
  • Containerbezogene Einheiten (cqw, cqh usw.) werden in Abfragebedingungen, Property-Deklarationen und Animations-Keyframes unterstützt. rem und em werden in Abfragebedingungen unterstützt.
  • Syntax für erweiterte Containerabfragen:
    • Bereichssyntax (z. B. (200px < width < 400px))
    • Gleichheitsabfragen (z. B. (width = 200px))
  • Pseudoelemente wie ::before und ::after
  • Browser ohne :is(...)/:where(...) werden über eine optionale Umgehung unterstützt.
  • Die Abfragen orientation und aspect-ratio
  • Abfragen werden richtig anhand von Funktionen gefiltert. Beispiel: Die Abfrage von height nach container: inline-size ist im horizontalen Schreibmodus korrekterweise nicht zulässig.
  • DOM-Mutation (z. B. wenn <style>- und <link>-Elemente zur Laufzeit entfernt werden)

Einschränkungen und Warnungen für Polyfills

Wenn Sie die Polyfill-Funktion für Containerabfragen verwenden, sind einige Funktionen nicht verfügbar:

  • Das Shadow-DOM wird noch nicht unterstützt.
  • Relative Containereinheiten (z. B. cqw und cqh) werden in Abfragebedingungen vom Typ @media nicht unterstützt.
    • Safari: Containerbezogene Einheiten werden in Animations-Keyframes vor Version 15.4 nicht unterstützt.
  • calc(), min(), max() oder andere mathematische Funktionen werden in Abfragebedingungen noch nicht unterstützt.
  • Diese Polyfill funktioniert nur mit Inline- und CSS-Code desselben Ursprungs. Seitenübergreifende Stylesheets und Stylesheets in Iframes werden nicht unterstützt, es sei denn, eine Polyfill wird manuell geladen.
  • Für die Begrenzung von layout und style ist die zugrunde liegende Browserunterstützung erforderlich:

Warnungen

  • Damit FID und CLS nicht beeinträchtigt werden, gibt der Polyfill keine Garantien dafür, wann das erste Layout auftritt, auch wenn es synchron geladen wird. Der Polyfill wird lediglich versuchen, eine übermäßige Verzögerung des LCP zu vermeiden. Mit anderen Worten: Sie sollten sich niemals auf die erste Darstellung verlassen.
  • Er generiert ResizeObserver Loop Errors. Das tut auch die ursprüngliche polyfill, aber es ist erwähnenswert. Dies liegt daran, dass sich die Blockgröße eines container-type: inline-size nach der Auswertung einer Abfrage wahrscheinlich ändert. ResizeObserver kann jedoch nicht mitteilen, dass Änderungen der Blockgröße keine Rolle spielen.
  • Diese Polyfill wurde anhand von Web-Plattformtests getestet und erreichte eine Bestehensquote von 70 %, da bestimmte Funktionen wie JavaScript APIs nicht polyfilled werden. Daher liegt die Bestehensquote bewusst bei etwa 70 %.
  • Die :where() Umgehung ist für die 2,23 % der Nutzer von Browsern erforderlich, die älter sind als:
    • Safari 14
    • Chromium 88
    • Edge 88
    • Samsung Internet 15
    • Firefox 78