CSS: Das Flexbox-Modul

Neben vorkonfektionierten Frameworks wie dem Responsive Grid System, xy.css, pure.css, Bootstrap oder UIkit mag der ein oder andere vielleicht lieber selber schrauben. Und von Grund auf verstehen, was da eigentlich passiert – oder daran verzweifeln und am Ende doch zu einem Grid-System von der Stange greifen 🙂

Für den Hobbyschrauber bietet CSS3 das Flexbox-Modul (Modul = Gruppe von CSS-Eigenschaften rund um display: flex;): Damit können in einem Container-Elternelement mehrere Kind-Elemente flexibel in Reihen und/oder Spalten angeordnet werden, auch wenn Ihre Ausmaße und Inhalte unbekannt, variabel oder einfach krass unterschiedlich sind.

Firefox Seit v.28 ohne Prefix.
Chrome Seit v.29 ohne Prefix.
Opera Seit v.17 ohne Prefix.
Safari Seit v.9 ohne Prefix.
Edge Seit v.12 ohne Prefix.
Internet Explorer v10 teilweise (mit Präfix -ms-),
ab v11 ohne Präfix, allerdings nicht vollständig.
Mobile Safari Seit iOS 9.2 ohne Prefix.
Android Browser Seit Android 4.4 ohne Prefix.

vgl. caniuse.com & shoudiprefix.com.

Sobald sich Windows 10 und damit Edge entsprechened verteilt haben, lässt sich das Flexbox-Modul sicherlich zu responsiven, auch komplexen und verschachtelten Seitenlayouts nutzen.

Bis dahin muss für die immer noch zahlreichen (für mich immer noch: unerklärbar vielen) IE10-User eine Fallback-Variante angeboten werden, wenn das Design cross-browser-kompatibel und plattform-übergreifend funktionieren soll. 🙁

Probleme wie „Gleiche Höhe von floatenden oder inline Divs mit unterschiedlichem Inhalt“ oder ähnliche Fragen lassen sich damit schick beantworten: Die Berechnung und Verteilung von Boxen innerhalb des Elterncontainers übernimmt der Brower. Schönen Dank dafür.

Hier ein erstes Beispiel und gleichzeitig die Stelle, an der ich über das Flexbox-Modul gestolpert bin:

>> Beispiel 01: inline-LIs vs. floatende DIVs vs. Flexbox

Wie immer: Die HTML-Dateien enthalten den gesamten notwendigen Code (HTML, CSS, evtl. JavaScript). Einfach herunterladen und anpassen 🙂

Diese schematische Abbildung soll die Grundbegriffe erläutern:

flexbox-basics
Innerhalb eines Containers können Items in verschiedener Richtung nach unterschiedlichen Regeln angeordnet werden.

Na dann: Schauen wir uns das Flexbox-Modul im Detail an.

Elterncontainer: Die Basics

Das Elternelement kann mit sechs Eigenschaften versehen werden:

  • display,
  • flex-direction,
  • flex-wrap,
  • justify-content,
  • align-items und
  • align-content:

display: Flexbox ön/öff

Neben den Standards wie block, inline und den table-Werten wird mit CSS3 für das Flexbox-Modul ein neuer Wert für die display-Eigenschaft eingeführt, welcher das Modul an-. bzw. ausschaltet:

.container {
  display: flex;
}

So weit, so einfach. Für den Elterncontainer können noch weitere Eigenschaften definiert werden, welche die Darstellung des Containers und der Kinderitems beeinflusst.


flex-direction: Zeile oder Spalte?

Die erste Eigenschaft ist die Richtung der Kinderelemente:

.container {
  flex-direction: row | column;
}

wobei row die Kinder zeilenweise darstellt, column dagegen als Spalte – klar, oder?.

>> Beispiel 02: Zeile oder Spalte?


flex-wrap: „Zeilenumbruch“ gefällig?

Bei einer zeilenweisen Ausrichtung kann man definieren, ob die „Zeile der Kinder“ umgebrochen werden soll oder nicht.

.container {
  flex-wrap: nowrap | wrap;
}

Dabei ist zu beachten, dass Teile weiterer CSS-Definitionen (z.B. die Breite der Kinder) ignoriert werden, wenn das Flexbox-Modul versucht, die Kinder gleichmäßig anzuordnen:

>> Beispiel 03: Zeilenumbrüche in der Reihe der Kinder


flex-flow: Kurzschreibweise

Für die beiden vorhergegangenen Definitionen gibt es eine Kurzschreibweise:

.container {
  flex-flow: [flex-direction-Wert] [flex-wrap-Wert];
}

Positionieren der „Kindergruppe“ innerhalb des Elterncontainers

Die gesamte Gruppe der Kinder kann über

  • justify-content,
  • align-items und
  • align-content

horizontal, vertikal und bzgl. des „Zeilenabstandes“ bei einem Zeilenumbruch (flex-wrap: wrap;) konfiguriert werden.


justify-content: Horizontale Ausrichtung

Soll die „Kindergruppe“ links-, rechtsbündig oder zentriert ausgerichtet werden oder gleichmäßig verteilt werden?

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

Für responsive Grid-Designs sind space-between und space-around „Gold wert“:

>> Beispiel 04: Horizontale Ausrichtung der Kindergruppe


align-items: Vertikale Ausrichtung

Soll die Kindergruppe innerhalb des Elterncontainers oben oder unten, mittig oder gedehnt dargestellt werden?

.container {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

Vor allem die Möglichkeit stretch ist ziemlich cool und macht diverse CSS- Workarounds für gleiche Höhe nebeneinander angeordneter Elemente überflüssig:

>> Beispiel 05: Vertikale Ausrichtung der Kindergruppe


align-content: Zeilenabstand bei mehrzeiligen „Kindergruppen“

Bei flex-wrap: wrap; und entsprechendem Umbruch der Kindelemente kann man mit align-content beeinflussen, wie die weiteren Zeilen angeordnet werden sollen. Zur Vereinfachung nenne ich diese Einstellung „Zeilenabstand“.

.container {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

Auch hier ist mein Lieblingswert stretch. Vor allem für „responsive Kacheldesigns“ ist das in Verbindung mit justify-content: space-around und align-items: stretch wird einem da eine Menge Pixelschubserei abgenommen 🙂

>> Beispiel 06: Zeilenabstand bei mehrzeiliger Darstellung


Kindelemente: Positionieren und ausrichten

Kindelemente können darüber hinaus via

  • flex-basis („Wunschbreite“ vorgeben),
  • flex-grow (Proportionen vergrößern),
  • flex-shrink (Proportionen verkleinern),
  • order (Manuelle Sortierung) und
  • align-self (Vertikale Ausrichtung für einzelne Kinder überschreiben)

gestaltet werden.

flex-basis („Wunschgröße“ vorgeben)

Mit der Angabe eines flex-basis-Wertes wird eine Breite bzw. Höhe der Kindelemente definiert (je nachdem, ob die flex-direction des Elternelementes row (dann: Breite) oder column (dann: Höhe) ist). Die Angabe kann in %, px, em, aber auch als auto angegeben werden:

.item {
  flex-basis: <px, %, em> | auto;
}

flex-grow bzw. flex-shrink (Proportionen vergrößern oder verkleinern)

Die flex-basis-Angabe ist allerdings beeinflussbar, indem ein flex-grow– bzw. flex-shrink-Wert angegeben wird. Diese beeinflussen die gleichmäßige Verteilung der Kindelemente um den entsprechenden Faktor: Wenn ein Kind einen grow-Wert von 2, alle anderen einen von 1 haben, wird das entsprechende Element etwa doppelt so breit angezeigt.

Gleiches funktioniert mit dem „Schrumpf“-Wert flex-shrink. Hier wird das entsprechende Kind im Verhältnis verkleinert.

flex: Kurzschreibweise

Für die drei obigen Werte gibt es eine Kurzschreibweise nach dem Strickmuster

.item {
  flex: [flex-grow-Wert] [flex-shrink-Wert] [flex-basis-Wert];
}

Der Standardwert ist 0 1 auto.

order (Manuelle Sortierung)

Mit der order-Angabe kann die Standard-Reihenfolge der Kinder manipuliert werden. Normalerweise werden die Elemente in der Reihenfolge gerendert, in der sie im Code stehen. Spezielle order-Angaben je item können das beeinflussen:

.item {
  order: <nummer>; 
}

align-self (Vertikale Ausrichtung für einzelne Kinder überschreiben)

Mit der align-self-Angabe einzelner Kindelemente kann die eigentlich für alle Kinder geltende align-items-Angabe des Elterncontainers überschrieben werden, z.B.:

.container {
  align-items: flex-start;
}
.item {
  align-self: flex-end;
}

Zulässige Werte sind flex-start, flex-end, center, baseline und stretch.

>> Beispiel 7: Kindelemente manipulieren


Anwendungsbeispiele

Den bereits hier mit einem CSS-Wokaround umgesetzten „Sticky Footer“ kann man deutlich einfacher mit dem Flexbox-Modul umsetzen. Dafür werden in einem Flexcontainer mit flex-direction: column; Header, Content und Footer untereinander angeordnet und der Content-Block via flex: 1 1 auto; so weit ausgedehnt wie möglich:

>> Flexboxed Sticky Footer


Mir nutzt das Flexbox-Modul besonders bei der Gestaltung von resposiven Rasterlayouts. Je nach Viewport werden unterschiedlich viele Spalten bzw. Elemente je Reihe angezeigt. Im Beispiel I kann man sehen, wie unterschiedlich viele Kindelemente je Elterncontainer bei gleicher CSS-Definition auf die Verkleinerung des Viewports reagieren. Einfach mal den Browser „schmaler schieben“:

>> Responsive Grid I


Dabei fällt auf, dass unterschiedlich viele Elemente zu einem eventuell unerwünschten Effekt führen: Wenn das letzte Kind einer Reihe umgebrochen wird, wird es gerne mit 100% Breite dargestellt, so dass manchmal drei Kinder in einer und das vierte Kind dreimal so breit in einer weiteren Reihe stehen.

Dagegen könnte man die Reihen in zwei Teile aufteilen und diese nebeneinander floaten, via @media queries bei bestimmten Viewportbreiten dann aber wieder anders anordnen:

>> Resposnive Grid II


Und wenn man die Beispiele von oben (Flexbox-Spalten für Header, Content, Footer + Flexbox-Reihen für Content-Boxen) kombiniert, erhält man ein

>> komplettes Seitenlayout

🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.