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
-
flex container
-
Laufrichtung der main-Achse mit
flex-direction
festlegen -
Umbruchrichtung/Richtung der cross-Achse mit
flex-wrap
festlegen -
Verteilung der flex items auf den verfügbaren Platz mit
justify-content
-
flex items entlang der cross-Achse mit
align-items
ausrichten -
Zeilen entlang der cross-Achse mit
align-content
verteilen
-
Laufrichtung der main-Achse mit
- flex items
- Anwendungsbeispiele
Ü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.
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).
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 Verschachtelung 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) margin
s 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.
Gleichmäßige/Lückenlose Verteilung von Links in einer Navigation
Eine gleichmäßige Verteilung von Links auf die gesamte Breite (oder Höhe) der
Navigation lässt sich ohne Flexbox mit margin
s 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 margin
s
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.