Florence Maurice

Webthemen

Layouten mit Gridlayout und mit Flexbox im Vergleich

Geschrieben am:

Lange Zeit hatten wir keine vernünftige Layouttechnik – und jetzt haben wir gleich zwei: Flexbox und Gridlayout. Gridlayout ist mächtiger, das ist klar. Brauchen wir damit überhaupt noch Flexbox? Diese Frage beantwortet man am besten an praktischen Beispielen – hier zeige ich ein Sticky-Footer-Layout, das dann erweitert wird, und führe vor, wie man das Layout in seinen Variationen jeweils mit Gridlayout und mit Flexbox umsetzt.

Sticky-Footer

Beginnen wir mit einem einfachen Sticky-Footer, d.h. ein Layout mit Fußbereich, wobei sich der Fußbereich auch bei wenig Inhalt immer ganz unten befindet.

sticky footer

Die Basis ist folgender Code:

<body> 
<header></header>
<article></article>
<footer></footer>
</body>

Sticky-Footer mit Flexbox

Sehen wir uns zuerst die Lösung mit Flexbox an:

body erhält eine Höhe von 100vh und wird zum Flexcontainer. Die Elemente sollten untereinander dargestellt werden – wofür flex-direction: column sorgt.

body { 
height: 100vh;
display: flex;
flex-direction:column;
}

((Ich nutze hier height und nicht min-height, damit der IE mitspielt, siehe Flexbox-Bugs.)) article soll den gesamten übrigen Platz bekommen – das erreichen wir mit flex: 1.

article { flex: 1; }

Sticky-Footer mit Flexbox ausprobieren

Sticky-Footer mit Gridlayout

Jetzt zur Lösung mit Gridlayout:

body wird dieses Mal zum Gridcontainer und wir definieren das einfache Raster: Es soll drei Zeilen (grid-template-rows) geben, die mittlere soll allen verfügbaren Platz einnehmen (1fr):

body { 
height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto;
}

Sticky footer mit Gridlayout ausprobieren

Beide Lösungen funktionieren. Ein entscheidender Unterschied zeigt sich in der Herangehensweise: Bei Gridlayout definieren wir alles beim Gridcontainer – hier steht die wesentliche Logik. Bei Flexbox sind Informationen über die Platzverteilung hingegen beim Flexitem untergebracht - in unserem Fall bei article, das allen verfügbaren Platz bekommen soll.

Welche Lösung ist besser?

Sehen wir uns einmal an, welche Lösung flexibler ist.

Erweitertes Layout – mit Flexbox

Erster Fall: Wir wollen eine weitere Zeile – beispielsweise für eine horizontale Navigation einführen.

zusätzliche Navigationszeile

Unser HTML-Code sieht damit folgendermaßen aus:

<body> 
<header><h2>Header</h2></header>
<nav><h2>Nav</h2></nav>
<article><h2>Mittelteil</h2></article>
<footer><h2>Footer</h2></footer>
</body>

Weiterhin soll article allen verfügbaren Platz einnehmen.

Bei der Flexbox-Lösung ist keinerlei Anpassung am CSS-Code notwendig.

Erweiterterer Sticky-Footer mit Flexbox

Erweitertes Layout mit Gridlayout

Bei Gridlayout müssen wir hingegen die Rasterdefinition anpassen – es sind jetzt schließlich vier Zeilen. Die Definition lautet jetzt grid-template-rows: auto auto 1fr auto;

body { 
display: grid;
grid-template-rows: auto auto 1fr auto;
}

Erweitertes Sticky-Footer-Layout mit Gridlayout

Dass die Logik im Gridcontainer steckt, hat eben diesen Nachteil. Allgemein ist Flexbox die bessere Wahl, wenn es eben nur um die Anordnung in einer Richtung geht – im Beispiel geht es ja nur um die Anordnung untereinander.

Komplexeres Layout

Jetzt erweitern wir unser Beispiel einmal anders - wir wollen im Hauptteil nicht nur ein article-Element, sondern drei:

<body> 
<header><h2>Header</h2></header>
<article class="art1"><h2>Mittelteil</h2></article>
<article class="art1"><h2>Mittelteil</h2></article>
<article class="art1"><h2>Mittelteil</h2></article>
<footer><h2>Footer</h2></footer>
</body>

Die grundlegende Darstellung bleibt: d.h. der Footer soll ganz unten sein.

Komplexeres Layout mit Gridlayout

Bei der Umsetzung hat  Gridlayout die Nase vorn. Und am einfachsten wird es, wenn man hier mit benannten Bereichen arbeitet:

body { 
display: grid;
grid-template-areas:
"head head head"
"art1 art2 art3"
"foot foot foot";
grid-template-rows: auto 1fr auto;
grid-template-columns: auto auto auto;
}

Die entscheidende Definition ist grid-template-areas: Hier lege ich die Aufteilung fest. Innerhalb der Anführungszeichen stehen jeweils die Bezeichnungen für eine Zeile, die einzelnen Strings innerhalb der Anführungszeichen definieren die einzelnen Spalten. In unserem Beispiel haben wir drei Zeilen und drei Spalten.

Wenn ein Element sich über mehrere Spalten erstrecken soll, so wiederhole ich den Namen. Die Bezeichnungen sind dabei frei gewählt.

Danach definiere ich die Ausmaße meines Rasters mit grid-template-rows (Zeilen) und grid-template-columns (Spalten). Die Größenangabe auto ist nützlich, wenn die Elemente einfach so groß werden sollen, wie es der Inhalt erforderlich macht. 1fr definiert, dass aller übriger Platz genutzt werden soll.

Danach weise ich im zweiten Schritt meine Elemente den oben definierten Bereichen zu:

header { 
grid-area: head;
}
footer {
grid-area: foot;
}
.eins {
grid-area: art1;
}
.zwei {
grid-area: art2;
}
.drei{
grid-area: art3;
}

Dreispaltiges Sticky-Footer-Layout mit Gridlayout umgesetzt

Dreispaltiges Sticky-Footer-Layout mit Flexbox - Variante 1: geänderter Quellcode

Wie könnte man diese Aufteilung mit Flexbox lösen? Es gibt m.E. zwei Möglichkeiten: zum einen können wir Flexbox verschachteln. Das heißt, wir packen ein main-Element um die drei Artikel. Damit haben wir einen geänderten Quellcode, nämlich folgendermaßen:

<body> 
<header><h2>Header</h2></header>
<main>
<article class="art1"><h2>Mittelteil</h2></article>
<article class="art1"><h2>Mittelteil</h2></article>
<article class="art1"><h2>Mittelteil</h2></article>
</main>
<footer><h2>Footer</h2></footer>
</body>

Und dann hat main eine Doppelrolle: Zum einen ist es Flexitem und nimmt den gesamten verfügbaren Platz in der Vertikalen ein. Zum anderen ist es selbst Flexcontainer für die article-Items, die nebeneinander dargestellt werden. Und da die article-Items den Platz unter sich aufteilen sollen, erhalten sie auch flex: 1.

body { 
display: flex;
flex-direction: column;
}
main {
display: flex;
flex: 1;
}
article {
flex: 1;
}

Dreispaltiges Sticky-Footer mit Flexbox - Variante 1 ausprobieren

Die Lösung klappt gut - aber wie gesagt mussten wir den HTML-Code verändern.

Dreispaltiges Sticky-Footer-Layout mit Flexbox - Variante 2: flex-wrap

Die andere Möglichkeit besteht im Einsatz von flex-wrap. Wir nehmen die spaltenweise Darstellung (der Standard), aber dank flex-wrap können die Elemente in die nächste Zeile gehen, wenn kein Platz mehr ist. Damit sich header und footer über die gesamte Breite erstrecken, erhalten sie eine flex-basis von 100%. Die drei article-Elemente sollen nebeneinander dargestellt werden und benötigen so eine Basisbreite von 33.3%:

body { 
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
header, footer {
flex-basis: 100%;
}
article {
flex-basis: 33.333%;
}

Außerdem sollen header und footer nicht ein Drittel des verfügbaren vertikalen Platz einnehmen, sondern ganz oben bzw. ganz unten angeordnet werden - dafür könnte ich mit align-self arbeiten, aber ich nehme hier margin.

header { 
margin-bottom: auto;
}
footer {
margin-top: auto;
}

Dreispaltiges Sticky-Footer mit Flexbox -Variante 2 ausprobieren Bei dieser Lösung gibt es allerdings eine Einschränkung - wenn man den article-Elementen Rahmen gibt (oder eine Hintergrundfarbe zuweist) - sieht man deutlich, dass die mittleren Elemente nicht den gesamten verfügbaren Platz einnehmen, sondern mittig angeordnet sind und nur so groß werden, wie es der Inhalt erfordert.

Das ist nicht immer ein Problem, aber es kann ein Problem sein. Dafür gibt es m.E. auch keine Lösung mit Flexbox. Und der Grund ist eben, dass Flexbox eindimensionale Steuerungen erlaubt und hier brauchen wir jetzt eine Steuerung in beide Richtung horizontal und vertikal - und genau dafür ist Gridlayout die bessere Wahl.

Fazit

Flexbox eignet sich gut für eindimensionale Layouts und ist dabei sehr flexibel, weil wir auch zusätzliche Elemente im HTML-Code ergänzen können, ohne etwas am CSS-Code ändern zu müssen. Für komplexere Layouts, d.h. Aufteilungen in der Horizontalen und in der Vertikalen, ist Gridlayout besser.