CSS Grid auto-fit / auto-fill – Responsive Layouts ohne Media Queries
Mit den CSS Grid-Funktionen repeat(), minmax() und dem auto-fit- bzw. auto-fill-Schlüsselwort können Responsive Layouts ohne Media Queries erstellt werden.
Die verschiedenen Darstellungsformen responsiver Website-Layouts werden üblicherweise mit Media Queries realisiert. Mit CSS Grid kann dank der minmax()
-Funktion und den Schlüsselwörtern auto-fit
bzw. auto-fill
allerdings auf Media Queries verzichtet werden. Das ist sehr komfortabel für Entwickler und führt zu stufenlos flexiblen Ansichten.
Die minmax()-Funktion
Mit Hilfe der CSS minmax()
-Funktion können Rasterzellen mit einer Mindest- und Maximalbreite versehen werden. Wie der Name der Funktion bereits andeutet, wird innerhalb der runden Klammern zuerst der Wert für die Mindestbreite des Elementes vergeben, anschließend mit Komma getrennt die Maximalausdehnung.
Der folgende Code erzeugt ein CSS Grid mit einer Zeile und drei Spalten. Beide Spalten sind mindestens 300 Pixel breit und maximal 500 Pixel breit.
.container {
display: grid;
grid-template-columns:
minmax(300px, 500px)
minmax(300px, 500px)
minmax(300px, 500px)
;
}
Details zur minmax()-Funktion findet ihr hier.
Die repeat()-Funktion
Wenn innerhalb eines CSS Grids Bereiche wiederholt werden sollen, so kann dafür die repeat()
-Funktion genutzt werden. Der 1. Wert in repeat()
steht für die Anzahl der Wiederholungen. Anschließend folgenden die gewünschten Grid-Eigenschaften.
Der folgende Code erzeugt das gleiche Ergebnis wie im vorherigen Beispiel, allerdings kürzer geschrieben, dank repeat()
;
.container {
display: grid;
grid-template-columns: repeat(3, minmax(300px, 500px));
}
Details zur repeat()-Funktion findet ihr hier.
Das auto-fit Schlüsselwort
Innerhalb der repeat()
-Funktion kann nun anstelle der Anzahl der Wiederholungen auch das Schlüsselwort auto-fit
verwendet werden. auto-fit
bedeutet in unserem Beispiel, dass unterschiedlich viele Spalten erzeugt werden, je nachdem wie viele in die Zeile des Grids passen.
Wenn also eine Spalte mindestens 300 Pixel schmal und maximal 500 Pixel breit sein soll, dann passen auf einem 1400 Pixel breiten Viewport vier Spalten nebeneinander. Diese würden sich bis zu einem Viewport von 1500 Pixel flexibel ausdehnen, dann passen fünf Elemente nebeneinander usw.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 500px));
}
Flexible Einheiten
Wenn nun die starren 300er-Pixelwerte durch flexible 1fr-Einheiten ersetzt werden, ist alles wunderbar responsive.
Der folgende Code erzeugt ein flexibles »auto-responsives« Raster, in dem Elemente immer mindestens 300 Pixel breit sind. Im Umkehrschluss reduziert das Grid automatisch die Anzahl der Spalten, sobald 300 Pixel unterschritten werden.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
auto-fit vs. auto-fill
Neben dem Schlüsselwort auto-fit
, existiert auch noch auto-fill
. Je nach Szenario kommt es vor, dass kaum ein Unterschied sichtbar ist. Am einfachsten ist der Unterschied erkennbar, wenn man die beiden Ansätze direkt vergleicht:
- auto-fit: Die Elemente passen sich dem verfügbaren Platz im Grid an und füllen die voll Breite aus
- auto-fill: Die Elemente passen sich nicht an. Das Grid erzeugt zusätzliche leere Spalten.
Minimale Breite der Elemente unterschreiten
Die bisher gezeigten Lösungen haben allesamt ein Problem: Die Objekte haben im Beispiel eine Mindestbreite von 300 Pixel zugewiesen bekommen. Die Spalten können sich daher ausdehnen – allerdings leider nicht in der minimalen Breite schrumpfen, da die 300px ja bereits den kleinsten Punkt definieren. Auf kleineren Viewports wird das Objekt daher angeschnitten.
Gelöst werden kann das Problem, indem noch einmal die min()
-Funktion verwendet wird:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
}
Sollte es in eurem Build-Prozess, im Sass-Compiler oder an vergleichbarer Stelle im Workflow zu einem Problem bei der Kompilierung kommen, schreibt den Code wie folgt um:
.grid {
display: grid;
grid-template-columns: #{'repeat(auto-fit, minmax(min(300px, 100%), 1fr))'};
}
Das stimmt leider nicht!
Wenn also eine Spalte mindestens 300 Pixel schmal und maximal 500 Pixel breit sein soll, dann passen auf einem 1400 Pixel breiten Viewport vier Spalten nebeneinander. Diese würden sich bis zu einem Viewport von 1500 Pixel flexibel ausdehnen, dann passen fünf Elemente nebeneinander usw.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 500px));
}
Denn nach dieser Logik sollten in einem Viewport von ca 600px, 2columns zu sehen sein. Allerdings entstehen die erst ab 2000px, woran liegt das?
Vielen Dank für deinen Kommentar, leider kann ich das von dir beschriebene Verhalten nicht nachvollziehen. Das Beispiel verhält sich so, wie oben im Text beschrieben. Was die Werte minimal verändert, sind die äußeren Umstände des Beispiels.
body
unddiv
haben beispielsweisemargin
undpadding
undborder
, so dass das Layout sich nicht bei exakt 1500 Pixeln verändert. Wenn ich diese Werte alle auf Null setze, reagiert es wie beschrieben.„Wenn also eine Spalte mindestens 300 Pixel schmal und maximal 500 Pixel breit sein soll, dann passen auf einem 1400 Pixel breiten Viewport vier Spalten nebeneinander. Diese würden sich bis zu einem Viewport von 1500 Pixel flexibel ausdehnen, dann passen fünf Elemente nebeneinander usw.“
Du hast da geschrieben gehabt, dass bei einem Viewport von 1500px, fünf Spalten entstehen, wenn die Vorraussetzung: grid-template-columns:repeat(autofit,minmax(300px, 500px) ist. Das stimmt leider nicht da hätten wir 3columns/Spalten.Der Grund ist der, dass alle Spalten gleich der maximale Ausdehnung sein müssen. Indem Falle passen in 1500px:500px, nur 3 Spalten. Erst wenn wir den Max mit „1fr“ machen, haben wir automatisch 5columns.
Hallo,
Irgendwas funktioniert da nicht, oder ich übersehe etwas.
Du schreibst zu nachfolgendem Snippet „Diese würden sich bis zu einem Viewport von 1500 Pixel flexibel ausdehnen“
„`
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 500px));
}
„`
Da dehnt sich aber nichts flexibel aus wenn man als Max-Argument nicht einen `fr` Wert nimmt. In Zusammenhang mit `auto-fit` wird offenbar nur der Wert des Max-Arguments genommen. Sobald es sich nicht mehr im Viewport ausgeht bricht die Column weg, die Elemente behalten immer die Max-Breite. Wenn man nicht auto-fit sondern z.B 3 Spalten angibt funktioniert es und die Elemente schrumpfen oder wachsen entsprechend der `minmax()`-Funktion.
Ich bitte um eine Demo, falls du der Meinung bist dass es doch wie von dir beschrieben funktioniert.
Ich habe den Beitrag noch einmal aktualisiert und den Unterschied zwischen auto-fill und auto-fit mit aufgenommen. Vielleicht löst das das Missverständnis?
Das mit autofit+minmax erscheint mir fast zu schön, um wahr zu sein. Funktioniert das auch mit verschieden großen Spalten und etwas komplexeren Layouts, z.B. für Artikelseiten mit grid-template-columns: 1fr 2fr 1fr und header, nav, article, aside, footer?
Möglicherweise kommt es dann nur auf clevere Werte für minmax an, aber es fällt schon auf, dass im Web fast immer nur Bildergalerien und cards (alle gleich groß) als Beispiele zu finden sind.
Vielen, vielen Dank,
ich habe ewig nach einem einfachen dreispaltigen und responsiven Design gesucht. Funktioniert wunderbar.
Sehr schöne Sache. Leider unterstützt der IE11 es nicht :-(
Nur wann können wir es auch wirklich einsetzen? :(
Wir haben es in aktuellen Projekten min Einsatz.
Danke für den tollen Beitrag! Diese Lösung ist soviel besser, als mit Media Queries zu arbeiten. Habe immer gedacht es muss bequemere Lösungen geben. CSS Rules! :)
Hilfreicher Artikel – wieder was gelernt :) Beim nächsten Projekt werde ich tatsächlich mal auf ein CSS-Grid zurückgreifen, die Unterstützung scheint inzwischen ausreichend gegeben.
Danke für den Beitrag, klingt verlockend das zu testen! Ich werde es bei meinem nächsten Projekt ausprobieren. Ich bin gespannt!
Hallo Jonas,
super Artikel, mir ist nur eine Kleinigkeit aufgefallen, in dem Codeblock „Flexible Einheiten“ steht bei minmax 33,333% – beim ansehen im Codebeispiel stimmt es dann mit 300px ;)
Werde das ganze definitiv mal bei uns testen :)
Besten Dank für den Hinweis mit dem 300 Pixeln. Ist jetzt behoben.
Funktioniert das in allen Browsern?
Was funktioniert schon in allen Browsern? Es funktioniert in allen projektrelevanten Browsern, für ältere haben wir eine saubere Lösungs als Fallback nach dem PE-Prinzip.
Den exakten Support findest du bei caniuse.
Sehr guter Artikel und super hilfreiche Funktion!
Im CSS steht auto-fill statt auto-fit :)
Ich finde das Feature auch super praktisch für einzelne Grid-Komponenten im Inhaltsbereich. Der Tipp-Fehler ist korrigiert.