Ein paar Abfragen der Containergröße hätten mir bei der Datenintelligenz von PlatoBlockchain geholfen. Vertikale Suche. Ai.

Ein paar Mal hätten mir Abfragen zur Containergröße geholfen

CSS-Containerabfragen gewinnen immer noch an Bedeutung und viele von uns machen sich damit die Hände nass, selbst wenn es um kleine Experimente oder so geht. Sie haben toll, aber nicht ganz voll, Browser-Unterstützung – genug, um ihre Verwendung in einigen Projekten zu rechtfertigen, aber vielleicht nicht in dem Maße, in dem wir versucht sein könnten, mit dem Ersetzen zu beginnen Medien-Anfragen aus früheren Projekten mit glänzenden neuen Containergrößenabfragen.

Sie sind aber sicher praktisch! Tatsächlich bin ich schon auf einige Situationen gestoßen, in denen ich sie wirklich erreichen wollte, aber die Supportanforderungen einfach nicht überwinden konnte. Hätte ich sie nutzen können, hätte es in diesen Situationen so ausgesehen.

Alle folgenden Demos lassen sich zum Zeitpunkt der Erstellung dieses Artikels am besten in Chrome oder Safari anzeigen. Firefox plant dies Schiffsunterstützung in Version 109.

Fall 1: Kartenraster

Damit musste man irgendwie rechnen, oder? Es ist so ein allgemeines Muster, dass wir alle irgendwann darauf stoßen. Tatsache ist jedoch, dass Abfragen in Containergröße für mich eine enorme Zeitersparnis mit einem besseren Ergebnis gewesen wären, wenn ich in der Lage gewesen wäre, sie gegenüber Standard-Medienabfragen zu verwenden.

Angenommen, Sie wurden beauftragt, dieses Kartenraster mit der Anforderung zu erstellen, dass jede Karte das Seitenverhältnis von 1: 1 beibehalten muss:

Ein paar Mal hätten mir Abfragen zur Containergröße geholfen

Es ist härter als es aussieht! Das Problem besteht darin, dass Sie durch die Größenanpassung des Inhalts einer Komponente an die Breite des Ansichtsfensters davon abhängig sind, wie die Komponente auf das Ansichtsfenster reagiert – und wie alle anderen Vorfahren-Container darauf reagieren. Wenn Sie beispielsweise möchten, dass die Schriftgröße einer Kartenüberschrift verringert wird, wenn die Karte eine bestimmte Inline-Größe erreicht, gibt es dafür keine zuverlässige Möglichkeit.

Du könntest die Schriftgröße einstellen vw Einheiten, nehme ich an, aber die Komponente ist immer noch an die Breite des Darstellungsbereichs des Browsers gebunden. Und das kann zu Problemen führen, wenn das Kartenraster in anderen Kontexten verwendet wird, die möglicherweise nicht dieselben Haltepunkte haben.

In meinem realen Projekt bin ich auf einen JavaScript-Ansatz gelandet, der Folgendes tun würde:

  1. Warten Sie auf ein Größenänderungsereignis.
  2. Berechnen Sie die Breite jeder Karte.
  3. Fügen Sie jeder Karte basierend auf ihrer Breite eine Inline-Schriftgröße hinzu.
  4. Gestalten Sie alles im Inneren mit em Einheiten.

Scheint eine Menge Arbeit zu sein, oder? Aber es ist eine stabile Lösung, um die erforderliche Skalierung über verschiedene Bildschirmgrößen in verschiedenen Kontexten zu erhalten.

Containerabfragen wären so viel besser gewesen, weil sie uns liefern Container-Abfrageeinheiten, so wie die cqw Einheit. Sie haben es wahrscheinlich schon verstanden, aber 1cqw entspricht 1% einer Containerbreite. Wir haben auch die cqi Einheit, die ein Maß für die Inline-Breite eines Containers ist, und cqb für die Blockbreite eines Containers. Also, wenn wir einen Kartenbehälter haben 500px breit, a 50cqw Wert berechnet sich zu 250px.

Wenn ich in meinem Kartenraster Containerabfragen hätte verwenden können, hätte ich die einrichten können .card Komponente als Container:

.card { 
  container: card / size;
}

Dann hätte ich noch eine Innenhülle mit setzen können padding das skaliert bei 10% dauert ebenfalls 3 Jahre. Das erste Jahr ist das sog. .card's Breite mit der cqw Einheit:

.card__inner { 
  padding: 10cqw; 
} 

Das ist eine gute Möglichkeit, den Abstand zwischen den Rändern der Karte und ihrem Inhalt konsistent zu skalieren, unabhängig davon, wo die Karte bei einer bestimmten Breite des Ansichtsfensters verwendet wird. Keine Medienabfragen erforderlich!

Eine andere Idee? Verwenden cqw Einheiten für die Schriftgröße des inneren Inhalts und wenden Sie dann eine Auffüllung an em Einheiten:

.card__inner { 
  font-size: 5cqw; 
  padding: 2em;
} 

5cqw ist ein willkürlicher Wert – nur einer, auf den ich mich festgelegt habe. Das Polster ist noch gleich 10cqw Da die em Einheit ist relativ zu .card__inner Schriftgröße!

Hast du das mitbekommen? Das 2em ist relativ zum 5cqw eingestellte Schriftgröße auf demselben Behälter. Container funktionieren anders als wir es gewohnt sind, als em Einheiten sind relativ zu denselben Elementen font-size value. Was mir jedoch schnell aufgefallen ist, ist, dass sich Container-Abfrageeinheiten beziehen der nächste Elternteil, der auch ein Container ist.

Zum Beispiel, 5cqw skaliert nicht basierend auf der .card Elementbreite in diesem Beispiel:

.card { 
  container: card / size; 
  container-name: card; 
  font-size: 5cqw; 
}

Vielmehr skaliert es auf das nächste übergeordnete Element, das als Container definiert ist. Deshalb habe ich eine eingerichtet .card__inner Verpackung.

Fall 2: Wechselndes Layout

Ich brauchte noch eine weitere Kartenkomponente in einem anderen Projekt. Dieses Mal brauchte ich die Karte, um von einem Querformat in ein Hochformat zu wechseln … dann zurück ins Querformat und wieder zurück ins Hochformat, wenn der Bildschirm kleiner wird.

Zeigt vier Zustände eines Kartenelements, die an verschiedenen Haltepunkten zwischen Hoch- und Querformat wechseln.
Ein paar Mal hätten mir Abfragen zur Containergröße geholfen

Ich habe die Drecksarbeit gemacht, diese Komponente in diesen beiden spezifischen Ansichtsfensterbereichen ins Hochformat zu bringen (rufen Sie die New Media-Abfragebereichssyntax!), aber auch hier besteht das Problem darin, dass es dann an die darauf eingestellten Medienabfragen, sein übergeordnetes Element und alles andere gebunden ist, das auf die Breite des Ansichtsfensters reagieren könnte. Wir wollen etwas, das unter allen Bedingungen funktioniert, ohne sich Gedanken darüber machen zu müssen, wo der Inhalt kaputt gehen wird!

Containerabfragen hätten dies dank der zum Kinderspiel gemacht @container Regel:

.info-card {
  container-type: inline-size;
  container-name: info-card;
}

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

Eine Abfrage, unendliche Fluidität:

Aber halt! Es gibt etwas, auf das Sie vielleicht achten sollten. Insbesondere könnte es schwierig sein, eine Containerabfrage wie diese in einem auf Props basierenden Designsystem zu verwenden. Zum Beispiel diese .info-card -Komponente könnte untergeordnete Komponenten enthalten, die auf Requisiten angewiesen sind, um ihr Aussehen zu ändern.

Warum ist das eine große Sache? Das Hochformat der Karte erfordert möglicherweise das alternative Design, aber Sie können JavaScript-Requisiten nicht mit CSS ändern. Daher riskieren Sie, die erforderlichen Stile zu duplizieren. Ich habe das tatsächlich angesprochen und wie man es umgeht in einem anderen Artikel. Wenn Sie Containerabfragen für einen erheblichen Teil Ihres Stylings verwenden müssen, müssen Sie möglicherweise Ihr gesamtes Designsystem darauf aufbauen, anstatt zu versuchen, sie in ein vorhandenes Designsystem einzufügen, das stark auf Medienabfragen basiert.

Fall 3: SVG-Striche

Hier ist ein weiteres sehr verbreitetes Muster, das ich kürzlich verwendet habe, bei dem Abfragen zur Containergröße zu einem ausgefeilteren Produkt geführt hätten. Angenommen, Sie haben ein Symbol mit einer Überschrift verschlossen:

Heading

Es ist ziemlich einfach, das Symbol mit der Größe des Titels zu skalieren, auch ohne Medienabfragen. Das Problem ist jedoch, dass die SVGs stroke-width könnte bei einer kleineren Größe zu dünn werden, um allzu gut wahrgenommen zu werden, und bei einer größeren Größe mit einem super dicken Strich zu viel Aufmerksamkeit erregen.

Ich musste Klassen erstellen und auf jede Symbolinstanz anwenden, um ihre Größe und Strichbreite zu bestimmen. Das ist in Ordnung, wenn sich das Symbol neben einer Überschrift befindet, die mit einer festen Schriftgröße gestaltet ist, denke ich, aber es ist nicht so toll, wenn man mit fließendem Typ arbeitet, der sich ständig ändert.

Ein Lockup eines sechseckigen Symbols und einer Überschrift in drei verschiedenen Größen, von groß bis klein.
Ein paar Mal hätten mir Abfragen zur Containergröße geholfen

Die Schriftgröße der Überschrift kann auf der Breite des Ansichtsfensters basieren, daher muss das SVG-Symbol entsprechend angepasst werden, wo sein Strich bei jeder Größe funktioniert. Sie könnten die Strichbreite relativ zu der Überschrift machen font-size indem man es einsetzt em Einheiten. Aber wenn Sie einen bestimmten Satz von Strichstärken haben, an die Sie sich halten müssen, dann würde dies nicht funktionieren, weil es sonst linear skaliert – es gibt keine Möglichkeit, es an eine bestimmte anzupassen stroke-width Wert an bestimmten Stellen ohne Rückgriff auf Medienabfragen auf die Viewport-Breite.

Aber hier ist, was ich getan hätte, wenn ich damals den Luxus von Containerabfragen gehabt hätte:

.icon {
  container: icon / size; 
  width: 1em; 
  height: 1em; 
}

.icon svg {
  width: 100%; 
  height: 100%; 
  fill: none; 
  stroke: #ccc; 
  stroke-width: 0.8; 
}

@container icon (max-width: 70px) {
  .icon svg {
    stroke-width: 1.5; 
  }
}
@container icon (max-width: 35px) {
  .icon svg {
    stroke-width: 3;
  }
}

Vergleichen Sie die Implementierungen und sehen Sie, wie die Container-Abfrageversion den Strich des SVG auf die spezifischen Breiten ausrichtet, die ich basierend auf der Breite des Containers haben möchte.

Bonus: Andere Arten von Containergrößenabfragen

OK, also bin ich bei einem echten Projekt nicht wirklich darauf gestoßen. Aber als ich Informationen zu Containerabfragen durchkämmte, bemerkte ich, dass es zusätzliche Dinge gibt, die wir zu einem Container abfragen können, die sich auf die Größe oder die physischen Abmessungen des Containers beziehen.

Die meisten Beispiele, die ich gesehen habe, fragen die ab width, max-width und min-width, height, block-size und inline-size wie ich es in diesem Artikel getan habe.

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

Jedoch müssen auch MDN skizziert zwei weitere Dinge können wir anfechten. Einer ist orientation was absolut sinnvoll ist, weil wir es ständig in Medienabfragen verwenden. Bei Containerabfragen ist das nicht anders:

@media screen (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

@container info-card (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

Das andere? Es ist aspect-ratio, glaub es oder nicht:

@container info-card (aspect-ratio: 3/2) { 
  .info-card__inner {
    /* Style away! */
  }
} 

Hier ist eine bearbeitbare Demo, um mit beiden Beispielen herumzuspielen:

Ich habe noch keinen wirklich guten Anwendungsfall für beides gefunden. Wenn Sie Ideen haben oder das Gefühl haben, dass es Ihnen bei Ihren Projekten hätte helfen können, lassen Sie es mich in den Kommentaren wissen!

Zeitstempel:

Mehr von CSS-Tricks