Design

CSS-Spalten-Layouts: Das Flexible Box Layout-Modul

21. Mai 2010
von

Wirkliche Spalten-Layouts mit automatischem Textumbruch, wie bei Print-Magazinen oder gedruckten Tageszeitungen, sind trotz float mit den bisherigen CSS-Standards nicht möglich. Mit CSS 3 soll das anders werden. Teils 1 der Artikelreihe über CSS-Spalten-Layouts beleuchtet das neue Flexible Box Layout.

Flexible Box Layout – oder einfach Flexbox – ist ein Modul, das vorwiegend von Mozilla spezifiziert wird. Das lässt sich allein daran erkennen, dass der Ansatz stark dem Prinzip von XML User Interface Language (XUL) ähnelt. XUL wurde von Mozilla entwickelt, um grafische UI-Elemente, wie kleine Widgets oder ganze Fenster in Form bringen zu können, ohne ein konkretes Design festlegen zu müssen. Das hört sich im ersten Moment seltsam an, doch tatsächlich steht bei der Benutzung von XUL die Trennung von Layout und Design im Fokus. Mit dieser Trennung kann der Entwickler dem Benutzer ermöglichen, seine Software ganz einfach mit eigenen Themes zu versehen. Für das Rendering der XUL-Oberflächen wird die Mozilla Gecko-Engine verwendet. Bekanntlich ist Gecko auch die Rendering-Engine des Firefox für HTML/CSS und JavaScript. Da liegt die Portierung des XUL-Prinzips auf CSS natürlich auf der Hand.

XUL stand Pate für die Flexbox.

Die Vorgeschichte

Das tiefgehende Verständnis der Herkunft von Flexbox ist insofern wichtig, als das es hilft, zu verstehen, wofür das Modul gedacht ist und vor allem wofür es nicht gedacht ist. In der Spezifikation zur Flexbox selbst wird das Modul als Ergänzung zu den bisherigen Boxmodellen beschrieben. Es soll das herkömmliche Boxmodell nicht ablösen, sondern ein neues Einsatzgebiet abdecken. Die Herkunft aus der Widget-Programmierung deutet darüberhinaus an, wo dieses Einsatzgebiet genau liegt. Obwohl man mit dem Flexbox-Modul auch sehr bequem ganze Seiten-Layouts verwirklichen könnte, kommen dessen Stärken eher bei den kleineren UI-Elementen, insbesondere bei Formularen zum Tragen.

Bevor wir gleich zum interessanten Teil kommen, sei hier noch ausdrücklich darauf hingewiesen, dass es sich bei der bisherigen Spezifikation um eine frühe Version, einen so genannten Working Draft, handelt. Das Grundprinzip wird sich höchstwahrscheinlich nicht mehr ändern, jedoch könnte es passieren, dass einige Eigenschaften einen anderen, präziseren Namen bekommen oder manche Details ausgebessert werden.

Das Grundprinzip von Flexbox

Damit wir uns auf das Wesentliche, also das CSS konzentrieren können, werden alle folgenden Regeln auf diese HTML-Struktur bezogen.

<div id="wrapper">
	<div id="eins"></div>
	<div id="zwei"></div>
	<div id="drei"></div>
</div>

Und damit man überhaupt etwas sieht, wird folgendes CSS als Grund-Styling vorausgesetzt. Im Laufe des Artikels werden diverse Auszeichnungen, die man hier sieht, überschrieben werden.

#wrapper {
	width: 600px;
	outline: 1px solid silver;
}

#eins,
#zwei,
#drei {
	width: 140px;
	height: 300px;
}

#eins {
	background: red;
}

#zwei {
	background: green;
}

#drei {
	background: blue;
}

Das bisherige Boxmodell kennt – wir unterschlagen hier der Einfachheit halber alle komplexeren Formen – drei Arten von Elementen: blocks, inlines und inline-blocks. Blocks ordnen sich untereinander an und sind mit margin und padding stylebar. Inlines verlaufen nebeneinander und brechen nur bei zu wenig horizontalem Raum um. Inline-Blocks sind eine Mischung aus beidem. Flexbox fügt dem bisherigen Arsenal an Layout-Typen einen weiteren hinzu. Mit display: box; macht man ein Element zu einer Box. Diese Box verhält sich nach außen wie ein Block-Element. Spannender ist aber, was mit den Kind-Elementen der Box geschieht.

#wrapper { display: box; }

Dieses CSS führt zu folgendem Erscheinungsbild:

Wie man sieht, werden die drei Blöcke in der Horizontalen nebeneinander platziert. Bis jetzt ist hier noch nichts flexibel, doch von flexibel steht ja auch noch nichts in unserem Stylesheet. Erst mit dem Attribut box-flex, das wir auf eines, mehrere oder alle Kind-Elemente anwenden, kommt Elastizität ins Spiel. Anhand zweier Beispiele wird die Funktionsweise klar:

Ein Element ist flexibel, die anderen beiden sind fest

#wrapper { display: box; }
#eins { box-flex: 1; }

Zwei Elemente sind flexibel, das andere ist fest
#wrapper { display: box; }
#eins { box-flex: 1; }
#zwei { box-flex: 1; }

Box-flex wirkt wie eine Spannfeder, welche das Element über die gesamte Fläche ausdehnt (dazu später mehr). Hat nur einer der drei Blöcke eine solche “Feder”, nimmt dieser den gesamten übrigen Platz ein. Gibt es mehrere dieser Blöcke mit Federn, müssen diese sich den Platz teilen. Die Aufteilung berechnet sich anteilhaft nach dem jeweiligen Box-Flex-Index. Je höher der Wert ist, den man der box-flex-Eigenschaft eines Elements zuweist, desto mehr Raum nimmt das Element in Anspruch – desto stärker ist die Spannfeder, um bei diesem Bild zu bleiben.

#wrapper { display: box; }
#eins { box-flex: 1; }
#zwei { box-flex: 7; }

Hier nimmt das zweite Element genau sieben Achtel des restlichen Raums zusätzlich ein, Block Eins nur ein Achtel. Die genaue Verteilung berechnet sich nämlich verhältnismäßig zwischen den box-flex-Werten aller Kind-Elemente einer Box. Hierin liegt der große Unterschied zu einer Bestimmung von width mit Prozentwerten. Die Prozentwerte sind zwar auch relativ, beziehen sich jedoch nur auf die Breite des Elternelements. Andere Blöcke, die neben diesem Element platziert sind, werden nicht beachtet. Box-Flex hingegen bezieht sich auf den verfügbaren Platz und alle anderen Blöcke, die sich mit um den Kuchen ranken.

Und wieder zurück zu dem Bild mit den Spannfedern: Eine starke Feder führt nicht unmittelbar zu einer stärkeren Ausdehnung, es müssen immer auch die Spannfedern aller anderen Elemente betrachtet werden.

Das ganze Spiel ist sowohl in vertikaler als auch horizontaler Ausrichtung möglich. Der Eigenschaft box-orient kann man die vier Werte horizontal, vertical, inline-axis und block-axis zuweisen.

  • horizontal: Die Elemente werden nebeneinander von links nach rechts angezeigt.
  • vertical: Die Elemente werden untereinander von oben nach unten angezeigt.
  • inline-axis: Hängt von dem Attribut writing-mode ab. Normalerweise provoziert inline-axis genau das gleiche Verhalten wie horizontal
  • block-axis: Hängt von dem Attribut writing-mode ab. Normalerweise provoziert block-axis genau das gleiche Verhalten wie vertical

Die Optionen inline-axis und block-axis finden in der Realität wahrscheinlich eher selten ein Anwendungsgebiet, auf dem sie ihre Stärke voll ausspielen können.

Trotzdem sollte man wissen, was diese Schlüsselwörter bewirken: Das Attribut writing-mode, beziehungsweise dessen horizontale Komponente direction und dessen vertikale Komponente block-progression, bestimmt die Leserichtung. So kann man etwa für den arabischen Raum einfach ein writing-mode: tb-rl notieren, und schon richten sich die Zeichen in der Horizontalen von rechts nach links aus.

Per writing-mode lassen sich Zeichen von rechts nach links anordnen.

Inline-Axis und Block-Axis folgen nun auch dieser Notation. Zwar werden die Stärken wie gesagt nur in den seltensten Fällen zum Tragen kommen, dennoch kann man die beiden Optionen stets den anderen beiden vorziehen. Man macht sich dadurch nichts kaputt, ist aber später deutlich flexibler, wenn sich der Chef entscheidet, nun doch nach Nahost oder Asien zu expandieren.

Richtung umkehren

Doch damit nicht genug. Will man jetzt noch zusätzlich die Richtung, in der die Elemente ausgerichtet sind, umkehren, hilft box-direction: reverse;. Die Eigenschaft könnte dann interessant werden, wenn man aufgrund der Semantik im Markup etwas anders gewichtet, als man es in der grafischen Ausgabe darstellen möchte. Wer die Ausrichtung nicht gleich komplett umkehren, sondern etwas präziser vorgehen möchte, kann sich box-ordinal-group zuhilfe nehmen. Weist man es mehreren Kind-Elementen der Box mit einer beliebigen Ganzzahl zu, wird das Element mit der niedrigsten Zahl zuvorderst angezeigt, das mit der höchsten als Letztes. Nach aufsteigenden Zahlen also der Ausrichtung entlang.

#wrapper { display: box; }
#eins { box-flex: 1; box-ordinal-group: 2; }
#zwei { box-flex: 1; box-ordinal-group: 3; }
#drei { box-flex: 1; box-ordinal-group: 1; }

Weist man einem Element diese Eigenschaft nicht zu, ist die box-ordinal-group automatisch auf 1 gesetzt. Das ist meiner Meinung nach ein kritischer Punkt in der Spezifikation, denn wenn man ein Element an den Anfang der Reihe setzen möchte, sollte das möglich sein, indem man nur dieses eine Element verändert. Da aber “1” die Standardeinstellung und zugleich der höchstmögliche Index ist, gestaltet sich das unmöglich. Es wäre noch möglich, einen Index von “0” zuzuweisen, doch das führt derzeit zu katastrophalen Ergebnissen bei den verschiedenen Browsern und in keinem Fall zu dem gewünschten Ergebnis. Ich denke, an diesem Punkt kann man noch einige Änderungen in der Spezifikation erwarten.

Hilfe, ich habe zu wenig oder zu viel Platz übrig!

Dass man entweder zu wenig oder zu viel Platz in seiner Flexbox hat, kann nur dann passieren, wenn keinem der Elemente box-flex zugewiesen wurde. Trotzdem ist es ganz hilfreich zu wissen, was mit dem Platz passiert und wie man ihn handhaben kann.

Mit zu viel Platz geht man genau gleich um, wie sonst auch. Mit overflow kann man bestimmen, ob man die Elemente einfach über die Box hinauslaufen lässt, ob man sie versteckt oder ihnen eine Scrollbar gewährt.

Anders sieht das bei zu wenig Platz aus. Hierzu gibt es zwei eigene Eigenschaften. Box-pack regelt den Raum in der Horizontalen, box-align in der Vertikalen.

box-pack für die Horizontale
start
Alle Elemente richten sich am Anfang der Eltern-Box aus. Der verbleibende Platz wird am Ende platziert.
end
Genau das gegenteilige Verhalten zu start.
justify
Zwischen jedes Element wird gleich viel Platz geschoben.
center
Die Elemente rücken zusammen und der restliche Platz wird links und rechts der Gruppe verteilt.
box-align für die Vertikale
start
Alle Elemente richten sich am Anfang der Eltern-Box aus. Der verbleibende Platz wird am Ende platziert.
end
Genau das gegenteilige Verhalten zu start.
center
Die Elemente rücken zusammen und der restliche Platz wird oberhalb und unterhalb der Gruppe verteilt.
baseline
Die Elemente richten sich nach ihrer typografischen Grundlinie aus.
stretch
Der restliche Raum wird den Höhen der Elemente gleichmäßig hinzugerechnet.

Browser-Support: Es sieht gut aus

Da die Spezifikation von Mozilla angetrieben wird und die Gecko-Engine derartige Layouts im Grunde schon seit Anfang ihres Bestehens interpretieren kann, ist es nicht verwunderlich, dass der Firefox ab Version 3.0.x das Modul größtenteils unterstützt. Auch die neueren Webkit-Browser lassen einen praktischen Einsatz des Moduls zu. Mit Firefox, Safari und Chrome hat man also schon einen Großteil des Browser-Spektrums abgedeckt. Und wenn wir einmal ehrlich sind, hätte auch niemand erwartet, dass der Internet Explorer in seiner jetzigen Form jemals eine derart fortschrittliche Technologie implementiert hätte.

Zwar sind die Implementationen in Gecko und Webkit noch experimentell, das heißt es werden vor jeder Eigenschaft die Präfixe -moz- und -webkit- gefordert, dennoch kann man es durchaus schon wagen, mit dem Modul das ein oder andere private Projekt zu gestalten.

(mm),

Markus Schlegel arbeitet als freier Webdesigner und bloggt über Web- und Icondesign, Typografie und Usability. Twitter,

6 Kommentare zu „CSS-Spalten-Layouts: Das Flexible Box Layout-Modul
  1. Dennis Frank am 21. Mai 2010 um 19:48

    Sehr interessant und praktisch. Vielen Dank für den Artikel, Markus.

  2. Marcus Dau am 24. Mai 2010 um 12:46

    Man darf gespannt sein, wann der “große” IE sich diesen Modelles annimmt.

    Ansonsten sehr schöner Artikel.

  3. Metric Stormtrooper am 25. Mai 2010 um 00:39

    Demoseite waere auf jeden fall praktisch damit man sich das mal am lebenden objekt mit verschiedenen browsern ansehen kann.

  4. Linkhub – Woche 20-2010 - pehbehbeh am 26. Mai 2010 um 13:25

    […] CSS-Spaltenlayouts: Das flexible Box-Layout-Modul. […]

  5. […] Serie CSS-3-SpaltenlayoutsCSS-3-SpaltenlayoutsCSS-Spaltenlayouts: Die zukünftigen MöglichkeitenCSS-Spalten-Layouts: Das Flexible Box Layout-ModulCSS-Spaltenlayouts: Das Grid Positioning-ModulCSS-3-Spaltenlayouts: Flexibler Textumbruch mit dem […]

  6. Alexander Genne am 21. Februar 2013 um 19:53

    Hallo Markus, vielen Dank für diesen Artikel.
    Ich kämpfe gerade mit dem flexbox layout und den Unterschieden in den vreschiedenen Browsern. Leider bekomme ich das gewünschte Layout gerade in Firefox nicht hin. Könntest Du Dir vielleicht das Problem anschauen: http://stackoverflow.com/questions/15008727/mozilla-flexbox-behavior-different-to-webkit-and-ie

    Danke im Voraus
    Grüße
    Alex

Ein Kommentar? Schön!

Wir freuen uns immer über Leser, die durch nützliche und konstruktive Beiträge zum Thema eine Diskussion anstoßen oder den Artikel mit weiteren Informationen anreichern. Alle Kommentare werden in diesem Sinne moderiert. Zum Kommentar-Fairplay gehört für uns auch der Einsatz von rel="nofollow". Bitte verwenden Sie zudem als Namen weder eine Domain noch ein spamverdächtiges Wort. Vielen Dank!