CSS3 Flexbox

Die Flexbox ist ein sehr mächtiger, umfangreicher Layoutmodus in CSS3. Wir haben uns mit dem Thema beschäftigt und eine ausführliche Anleitung mit einer Reihe von Beispielen erstellt, um dieses komplexe Thema anschaulich zusammenzufassen.

Inhalt

Über Flexboxen

Flexboxen bieten sehr flexible Layouts, die in Apps oder einzelnen Webseiten-Komponenten zum Einsatz kommen können und insbesondere dann glänzen, wenn die Größe von Inhalten nicht bekannt ist. Außerdem kann man mit ihnen viele unschöne CSS-Hacks wie floats und tables umgehen. Sie sind wegen ihrer Flexibilität und der Möglichkeit, Inhalte neu zu ordnen auch im Hinblick auf Responsive Design ein nützliches Tool.

Bis auf einige Bugs in IE10-11 werden Flexboxen von allen modernen Browsern unterstützt.

Man unterscheidet zwischen dem Container (flex container) und den darin eingebetteten Inhalten (flex items). Für beide gibt es eine Reihe eigener CSS-Eigenschaften, die das jeweilige Verhalten festlegen.

Der flex container bestimmt die Flussrichtung der Inhalte sowie die Abstände zwischen ihnen. Die flex items kümmern sich um ihre eigene Größe und können nach Bedarf noch einzeln neu positioniert werden.

flex container

Nahezu jedes Element kann als flex container verwendet werden, indem man ihm die Eigenschaft display: flex zuweist.

Einige Browser haben kleine Bugs, sodass bestimmte Elemente nicht als flex container funktionieren, wie zum Beispiel Buttons in Firefox. Als Workaround kann man aber einfach ein anderes Element – zum Beispiel ein div – einbetten und dieses dann als flex container verwenden.

Der flex container hat zwei Achsen: Die main-Achse, die die eigentliche Flussrichtung widerspiegelt, und die cross-Achse, die die Richtung für Zeilenumbrüche vorgibt. Beide Achsenrichtungen können nach eigenen Wünschen angepasst werden.

Zwei mögliche Achsen-Konfigurationen Im Bild: Zwei mögliche Achsen-Konfigurationen: flex-direction: row (links) und flex-direction: column (rechts)


Jede Achse hat einen Start- und Endpunkt, sowie eine Länge (size).

Achsen start, end und size Im Bild: Veranschaulichung von start, end und size der beiden Achsen


Laufrichtung der main-Achse mit flex-direction festlegen

Insgesamt gibt es vier Möglichkeiten für die Laufrichtung: Von links nach rechts mit row (Standard), von rechts nach links mit row-reverse, von oben nach unten mit column und von unten nach oben mit column-reverse.

See the Pen flex-direction-example by Linda Grünwald (@lindagruenwald) on CodePen.

Umbruchrichtung/Richtung der cross-Achse mit flex-wrap festlegen

Hierfür gibt es drei Möglichkeiten: nowrap (Standard) verhindert Zeilenumbrüche, sodass alle flex items in eine Reihe bzw. Spalte gebracht werden, wrap sorgt für die für uns “gewohnte” Umbruchrichtung und wrap-reverse für die umgekehrte. “Gewohnte” Umbruchrichtung heißt: von oben nach unten bei horizontaler main-Achse und von links nach rechts bei vertikaler main-Achse, so wie man es vom Lesen allgemein gewohnt ist. nowrap erlaubt zwar keine Umbrüche, setzt die eigentliche cross-Achse aber auf dieselbe Richtung wie wrap. Dies ist für die Ausrichtung von flex items mit zum Beispiel align-items (siehe unten) notwendig.

See the Pen flex-wrap-example by Linda Grünwald (@lindagruenwald) on CodePen.

Verteilung der flex items auf den verfügbaren Platz mit justify-content

Falls der flex container auf der main-Achse mehr Platz bietet, als die flex items einnehmen, kann der übrige Platz mit justify-content noch zwischen den flex items verteilt werden. Man kann diese Eigenschaft als eine Art text-align für flex items auffassen.

Es stehen fünf Werte zur Verfügung: flex-start (Standard) lässt die flex items am Anfang der main-Achse anliegen, flex-end analog dazu am Ende. center zentriert sie in der Mitte und die beiden Werte space-between und space-around entsprechen einer Art Blocksatz: Die flex items werden gleichmäßig auf die volle main-Achsen-Länge des flex containers verteilt, wobei bei space-around zusätzlich noch vor dem ersten und nach dem letzten Element Platz eingeschoben wird, bei space-between jedoch nur zwischen ihnen.

See the Pen justify-content-example by Linda Grünwald (@lindagruenwald) on CodePen.

flex items entlang der cross-Achse mit align-items ausrichten

Die flex items können auf verschiedene Weise entlang der cross-Achse positioniert werden. Der Standard ist stretch, d.h. sie werden alle auf die maximale Größe gedehnt. Bei den übrigen vier Werten bleibt die ursprüngliche Größe erhalten. Diese Werte sind flex-start (lässt alle flex items am Anfang der cross-Achse anliegen), flex-end (lässt alle am Ende anliegen), center (zentriert die flex items) und baseline. Letzteres richtet die flex items anhand der jeweils ersten Grundlinie zueinander aus. Falls verschiedene flex items also in der ersten Zeile verschiedene Zeilenhöhen haben, werden sie gegeneinander verschoben, bis die erste Grundlinie bei allen auf der gleichen Höhe liegt.

See the Pen align-items-example by Linda Grünwald (@lindagruenwald) on CodePen.

Zeilen entlang der cross-Achse mit align-content verteilen

Falls ein mehrzeiliger flex container auf der cross-Achse Platz übrig hat, können mit dieser Eigenschaft mehrere Zeilen verteilt werden, analog zur Verteilung einzelner flex items mit justify-content. Demzufolge stehen auch die selben Werte zur Verfügung. Bei einzeiligen Flexboxen hat align-content keine Auswirkung.

Zusätzlich zu den aus justify-content bekannten Werten wird hier noch stretch angeboten, welcher alle Zeilen ausdehnt, sodass kein Leerraum mehr zwischen den Zeilen besteht. Dieser Wert ist jedoch nicht mit dem stretch von align-items zu verwechseln, er hat keine eigene Auswirkung auf die Größe der flex items, sondern nur auf die der Zeile, in der diese stehen. Mit stretch ausgerichtete Zeilen haben nicht (zwingend) alle die selbe Größe, sondern sie bekommen alle den gleichen Anteil vom übrigen Platz zugewiesen, den es zu verteilen gilt. Falls die Zeilen vorher schon wegen ihrer Inhalte verschiedene Größen hatten, haben sie dies mit stretch immer noch.

See the Pen align-content-example by Linda Grünwald (@lindagruenwald) on CodePen.

flex items

Die flex items können ihre eigene Größe, Positionierung und Reihenfolge, die der flex container ihnen vorgibt, überschreiben. Alles, was der flex container enthält, ist automatisch ein flex item, sogar ohne zusätzliche Ver­schach­te­lung eingebetteter Text. Es ist keine extra CSS-Eigenschaft dafür notwendig. Flex items können daher auch ohne Probleme selbst wieder eigene flex container sein, wenn dies gewünscht ist.

Flex items können jeden beliebigen Wert für display verwenden. Der flex container behandelt sie unabhängig davon alle ähnlich wie block-Elemente.

Reihenfolge mit order festlegen

Mit dieser Eigenschaft kann die vom DOM vorgegebene Reihenfolge der flex items überschrieben werden. Vor allem für responsive Anwendungen ist diese Möglichkeit sehr praktisch. order bekommt einen Integer Wert zugewiesen, der negativ, 0 (Standard) oder positiv sein darf. Die Reihenfolge funktioniert dann ähnlich wie eine Rangliste: Je niedriger der Wert ist, desto weiter vorne steht das Element. Mehrere flex items mit gleichem Wert werden in ihrer DOM-Reihenfolge angezeigt.

See the Pen order-example by Linda Grünwald (@lindagruenwald) on CodePen.

flex items mit flex-grow ausdehnen lassen

Diese Eigenschaft bekommt einen positiven Integer-Wert oder 0 (Standard) zugewiesen. Der übrige Platz auf der main-Achse der jeweiligen Zeile wird innerhalb aller flex items mit einem positiven Wert verteilt, proportional zum angegebenen Wert. Ein Element mit dem Wert 2 bekommt demzufolge doppelt so viel vom übrigen Platz als ein Element mit dem Wert 1. Der Platz wird in das Element hinein verlegt, d.h. das Element wird größer, nicht die Abstände zwischen ihnen.

Sobald mindestens ein flex item einen positiven Wert hat, zeigt justify-content vom flex container nur dann noch sichtbare Wirkung, wenn die wachsenden Elemente aufgrund von max-width oder max-height eingeschränkt sind, da es sonst keinen übrigen Platz mehr zu verteilen gibt.

See the Pen flex-grow-example by Linda Grünwald (@lindagruenwald) on CodePen.

flex items mit flex-shrink schrumpfen lassen

Ebenso wie bei flex-grow wird hier ein positiver Integer-Wert oder 0 vergeben. Der Standard ist 1. Auch hier sind die Werte proportional zu verstehen, ein Element mit dem Wert 2 muss doppelt so sehr schrumpfen wie eines mit dem Wert 1. flex-shrink skaliert Elemente nicht unter die Mindestgröße. Im Gegensatz zu flex-grow bezieht sich flex-shrink auf den maximal verfügbaren Platz im ganzen flex container, nicht nur auf den in einer Zeile. Mit verschiedenen Werten kann sich also auch der Umbruch verschieben.

See the Pen flex-shrink-example by Linda Grünwald (@lindagruenwald) on CodePen.

flex items mit flex-basis eine Standardgröße zuweisen

Diese Eigenschaft weist jedem Element eine Standardgröße in der main-Achsen-Richtung zu. Der Wert kann von flex-grow und flex-shrink trotzdem noch verändert werden. Er ist daher nicht mit min- oder max-Werten gleichzusetzen. Der Standard ist auto.

See the Pen flex-basis-example by Linda Grünwald (@lindagruenwald) on CodePen.

Abkürzung flex

Dies ist eine Abkürzung für flex-grow, flex-shrink und flex-basis. Der Standard ist demzufolge 0 1 auto. Aufgrund eines IE10-11 Bugs ist es ratsam, beim flex-basis-Wert immer eine Einheit anzugeben, auch wenn es nur 0 sein soll (zum Beispiel 0%). Andernfalls wird die Zahl als einer der anderen beiden Werte interpretiert. Es empfielt sich auch, nicht 0px zu verwenden, da dies in komprimiertem CSS unter Umständen wieder zu 0 ohne Einheit wird.

flex items entlang der cross-Achse mit align-self einzeln ausrichten

Damit kann man den align-items-Wert bei einzelnen flex items überschreiben. Demzufolge stehen die selben Werte wie bei align-items zur Verfügung, sowie zusätzlich auto (Standard), was den Wert vom flex container übernimmt.

Bei baseline besteht noch die Besonderheit, dass mindestens zwei flex items diesen Wert haben müssen, damit er Wirkung zeigt, da sich die Grundlinie nur bei diesen Elementen angleicht. Jedes baseline-Element benötigt also mindestens ein weiteres als Bezugselement.

See the Pen align-self-example by Linda Grünwald (@lindagruenwald) on CodePen.

Anwendungsbeispiele

Wann man Flexbox verwenden sollte

In der Regel ist Flexbox besser als CSS-Hacks mit float, table oder position, da diese umständlich zu handhaben, fehleranfällig und häufig unflexibel sind. Allerdings ist die Flexbox eher nicht für allzu komplexe Komponenten, wie etwa das Hauptlayout der Webseite, geeignet. Zum einen liegt das am Ladeverhalten von Webseiten. Wenn einzelne flex items schon geladen sind, andere aber noch nicht, kann dies unter Umständen zeitweise zu fehlerhafter Darstellung führen, wenn die geladenen Elemente zum Beispiel aufgrund von flex-grow das komplette Fenster ausfüllen dürfen. Außerdem ist es häufig umständlich, vorgegebene komplexe Strukturen in Flexbox umzusetzen. Wenn man ein ganz exaktes Layout mit bestimmten Spaltenbreiten, Spaltenanzahlen, Umbrüchen etc. hat, die eingehalten werden müssen, sollte man besser ein Grid nutzen. Flexbox-Grids sind teilweise schon in einigen CSS-Frameworks wie Foundation 6 enthalten und werden in Zukunft vermutlich eine immer größere Rolle spielen, im Moment sind sie aber noch eher selten anzutreffen.

Grob gesagt ist die Flexbox immer dann gut, wenn sich die Darstellung an den Inhalt anpassen soll. Hier steht die Flexibilität im Vordergrund. In der Regel betrifft dies einzelne Komponenten in einer Webseite, wie etwa eine Übersicht, Galerie oder ähnliches. Auch für responsive Komponenten ist die Flexbox eine gute Wahl. Wenn die Darstellung fest und relativ komplex aufgebaut ist und der Inhalt sich an diese anzupassen hat, sollte man eher auf Grids zurückgreifen.

Perfekte vertikale Zentrierung

Während horizontale Zentrierung einfach mit margin: 0 auto bzw. text-align: center lösbar ist, ist vertikale Zentrierung ein häufiges Problem und eine der besten Anwendungen für eine Flexbox. Bei Lösungen mit block- oder inline-Elementen muss für perfekte vertikale Zentrierung die Containerhöhe bekannt sein, was in vielen flexiblen und responsiven Bereichen nicht der Fall ist. Eine Lösung mit table wäre zwar möglich, ist aber um eine Stufe umständlicher als mit einer Flexbox. Außerdem lässt sich mit Flexbox sogar direkt eingebetteter Text ohne weitere Verschachtelung zentrieren. Unten der Vergleich zwischen der table und der flex Lösung.

See the Pen vertical-center-example by Linda Grünwald (@lindagruenwald) on CodePen.

Basic App Layout

Da das Layout einer App in der Regel sehr simpel gehalten ist, kann man hier die Regel, kein Hauptlayout mit Flexbox zu bauen ignorieren, da die Auswirkungen der oben genannten Nachteile minimal sind.

Die meisten Apps haben einen fixierten Header und/oder Footer. Die offensichtlichere Lösung mit position: fixed nimmt jedoch die Elemente aus dem Seitenfluss heraus, sodass sie fortan über dem Inhalt liegen. Dann muss mit (unter Umständen dynamisch berechneten) margins gearbeitet werden, um sicherzustellen, dass Anfang und Ende des Inhalts noch sichtbar sind.

Einfacher geht dies mit einer vertikal angeordneten Flexbox mit drei flex items. Diese liegen perfekt nebeneinander, sodass oben genanntes Problem nicht auftritt. Die fixierte Position kann man erreichen, indem Header und Footer eine feste Höhe haben, weder wachsen noch schrumpfen dürfen und an den Anfang bzw. das Ende der main-Achse gelegt werden. Der Inhalt muss sich ausdehnen können, um den restlichen Platz zu füllen, und scrollbar sein.

See the Pen app-layout-example by Linda Grünwald (@lindagruenwald) on CodePen.

Eine gleichmäßige Verteilung von Links auf die gesamte Breite (oder Höhe) der Navigation lässt sich ohne Flexbox mit margins nur ungefähr simulieren und muss angepasst werden, sobald sich die Linkanzahl oder -länge ändert. Eine lückenlose Darstellung von inline Elementen muss auch mit margins angepasst werden, da standardmäßig 4px Abstand zwischen diesen eingehalten wird.

Unten stehen zwei Lösungen mit Flexbox, einmal mit und einmal ohne lückenlose Verteilung. Zusätzlich wurden die Links vertikal mit Flexbox zentriert.

See the Pen nav-verteilung-example by Linda Grünwald (@lindagruenwald) on CodePen.

Gleichmäßige Spaltenhöhen

Häufig findet man horizontale Auflistungen von gleich großen Elementen, deren Inhalte unterschiedliche Längen haben. Eine feste Höhe zuzuweisen ist riskant, da man in der Regel die tatsächliche Länge der Elemente nicht kennt und somit die Möglichkeit besteht, dass der Inhalt abgeschnitten wird oder überläuft. Trotzdem möchte man alle Elemente auf eine einheitliche Höhe bringen. Wieder steht als Alternative table zur Verfügung, jedoch ist dies umständlicher als eine Flexbox.

See the Pen gleichmäßige-spaltenhöhen-example by Linda Grünwald (@lindagruenwald) on CodePen.

Bildergalerien/Auflistungen

Für Galerien oder ähnliches mit flexiblen Maßen ist eine Flexbox eine schöne Alternative zu einem Grid, da die Spaltenanzahl automatisch durch Umbrüche geregelt wird. Dank der vielen verschiedenen Einstellungsmöglichkeiten kann man auch frei festlegen, ob die Elemente skaliert werden dürfen, wie sie sich ausrichten sollen etc.

Zur Veranschaulichung der Flexibilität ist der Galerie-Container im Beispiel unten größenverstellbar.

See the Pen gallery-example by Linda Grünwald (@lindagruenwald) on CodePen.

Umsortierung von Inhalten in mobiler Ansicht

Manchmal sollen Inhalte in der mobilen Ansicht nicht in der gleichen Reihenfolge dargestellt werden, wie sie im DOM liegen, zum Beispiel wenn auf der Desktopversion Inhalte im Zig-Zag-Layout dargestellt werden und der DOM sie in Lesereihenfolge auflistet. Da in der Mobilversion die Inhalte nur noch an der vertikalen Achse ausgerichtet werden, nicht mehr horizontal, würde die Zig-Zag-Anordnung im DOM einer ständig wechselnden Reihenfolge der Elementtypen führen, die man vermeiden möchte. Diese Inhaltssprünge kann man mit order ausgleichen.

Zur Simulation der responsiven Umgebung ist das untenstehende Beispiel in einer größenverstellbaren Box platziert.

See the Pen by Linda Grünwald (@lindagruenwald) on CodePen.