Ein automatisch befüllbares CSS-Grid mit maximaler Spaltenanzahl bei einer Mindestgröße

Avatar of Mike Herchel
Mike Herchel am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Innerhalb von Drupal 10 Core implementieren wir eine neue automatische CSS-Grid-Technik, die meiner Meinung nach cool genug ist, um sie mit der Welt zu teilen.

Die Anforderungen sind

  • Der Benutzer gibt eine maximale Anzahl von Spalten an. Dies ist der "natürliche" Zustand des automatisch befüllbaren Grids.
  • Wenn eine Grid-Zelle eine vom Benutzer angegebene Breite unterschreitet, passt sich das automatisch befüllbare Grid an und verringert die Anzahl der Spalten.
  • Die Grid-Zellen sollten sich immer so dehnen, dass sie die Breite des automatisch befüllbaren Grid-Containers ausfüllen, unabhängig von der Spaltenanzahl.
  • All dies sollte unabhängig von der Ansichtsfensterbreite funktionieren und kein JavaScript erfordern.
Screenshot showing the auto-filling CSS Grid's settings in Drupal.

Das automatisch befüllbare CSS-Grid in Aktion

Hier sehen Sie, wie sich das resultierende automatisch befüllbare CSS-Grid verhält, wenn es durch das ziehbare Div-Element links davon komprimiert wird.

Hier ist der Code

Wenn Sie nicht an der Theorie hinter dem automatisch befüllbaren Grid interessiert sind und einfach nur Code kopieren/einfügen möchten, hier ist er!

.grid-container {
  /**
   * User input values.
   */
  --grid-layout-gap: 10px;
  --grid-column-count: 4;
  --grid-item--min-width: 100px;

  /**
   * Calculated values.
   */
  --gap-count: calc(var(--grid-column-count) - 1);
  --total-gap-width: calc(var(--gap-count) * var(--grid-layout-gap));
  --grid-item--max-width: calc((100% - var(--total-gap-width)) / var(--grid-column-count));

  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(max(var(--grid-item--min-width), var(--grid-item--max-width)), 1fr));
  grid-gap: var(--grid-layout-gap);
}

Theorie und Werkzeuge hinter dem automatisch befüllbaren CSS-Grid

Der obige Code verwendet mehrere moderne CSS-Werkzeuge, darunter die Funktionen repeat(), auto-fill() und minmax() von CSS Grid sowie die CSS-Funktionen max() und calc(). Hier ist, wie es funktioniert.

Die auto-fill()-Funktion von CSS Grid

Der Schlüssel zu all dem ist auto-fill(). Wir möchten, dass jede Zeile mit so vielen Spalten wie möglich gefüllt wird. Für weitere Informationen zu auto-fill lesen Sie den großartigen Artikel von Sara Soueidan über den Unterschied zwischen auto-fill und auto-fit, der dieses hilfreiche Video enthält, das zeigt, wie es funktioniert.

Aber wie stellen wir sicher, dass es nicht *zu viele* Spalten auffüllt?

Die CSS-Funktion max()

Dafür ist die Funktion max() da! Wir möchten, dass die Breite jeder Grid-Zelle maximal einen bestimmten Prozentsatz beträgt, sagen wir 25% für ein Grid mit vier Spalten. Aber sie darf nicht unter die vom Benutzer angegebene Mindestbreite fallen.

Unter der Annahme eines Grids mit vier Spalten und einer Mindestbreite der Zelle von 100px würde die Funktion max() etwa so aussehen: max(25%, 100px).

Der Wert 25% ist jedoch immer noch nicht ganz korrekt, da er die Grid-Abstände nicht berücksichtigt. Was wir wirklich brauchen, ist stattdessen etwas wie dies:

max(calc(25% - <grid-gap-for-one-cell>), 100px)

Das können wir in CSS mit calc() berechnen! (Wer sagt, CSS sei keine Programmierung?)

--gap-count: calc(var(--grid-column-count) - 1);
--total-gap-width: calc(var(--gap-count) * var(--grid-layout-gap));
--grid-item--max-width: calc((100% - var(--total-gap-width)) / var(--grid-column-count));

Jetzt haben wir einen weiteren Schlüssel, um dies zu ermöglichen! Dies weist der Grid-Zelle an, ihre maximale Breite zu erreichen (die die vom Benutzer angegebenen Spalten berücksichtigt), wird aber niemals kleiner als 100px.

max(100px, var(--grid-item--max-width))

Erfahren Sie mehr über die Funktion max() in Chris Coyiers Artikel über die CSS-Funktionen min(),max() und clamp().

Die minmax()-Funktion von CSS Grid

Wir nähern uns, aber eine wichtige Zutat fehlt noch: Das Grid dehnt sich nicht immer auf die Breite seines übergeordneten Containers aus.

Genau dafür ist die Funktion minmax() konzipiert. Die folgende CSS legt die Mindestbreite auf die <grid-item-width> fest, und wenn Platz vorhanden ist, dehnt sie alle Zellen gleichmäßig aus, um die Breite des übergeordneten Elements auszufüllen!

minmax(<grid-item-width>, 1fr)

Fassen wir alles zusammen und zaubern!

Mit den oben genannten Werkzeugen können wir dieses magische Stück Code zusammenstellen, das genau das tut, was wir wollen!

--gap-count: calc(var(--grid-column-count) - 1);
--total-gap-width: calc(var(--gap-count) * var(--grid-layout-gap));
--grid-item--max-width: calc((100% - var(--total-gap-width)) / var(--grid-column-count));

grid-template-columns: repeat(auto-fill, minmax(max(var(--grid-item--min-width), var(--grid-item--max-width)), 1fr));

CSS macht Spaß!

CSS hat sich wirklich weiterentwickelt. Ich hatte viel Spaß bei der Arbeit daran, und ich bin so glücklich, dass Anwendungsfälle wie dieser jetzt ohne JavaScript möglich sind.

Besonderer Dank an Andy Blum, der auto-fill() gegenüber auto-fit() vorgeschlagen hat. Außerdem ein besonders großer Dank an alle Implementierer und Spezifikationsautoren, die fortgeschrittene Funktionen wie diese standardisiert und möglich machen.