Spaces. Smartes Cloud Hosting für anspruchsvolle Webprojekte. Loslegen und Spaces testen. Von Mittwald.
Markus Schlegel 21. Mai 2010

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

Wirkliche Spalten-Layouts mit auto­ma­ti­schem Textumbruch, wie bei Print-Magazinen oder gedruck­ten Tageszeitungen, sind trotz float mit den bis­he­ri­gen CSS-Standards nicht mög­lich. Mit CSS 3 soll das anders wer­den. Teils 1 der Artikelreihe über CSS-Spalten-Layouts beleuch­tet das neue Flexible Box Layout.

Flexible Box Layout – oder ein­fach Flexbox – ist ein Modul, das vor­wie­gend von Mozilla spe­zi­fi­ziert wird. Das lässt sich allein dar­an erken­nen, dass der Ansatz stark dem Prinzip von XML User Interface Language (XUL) ähnelt. XUL wur­de von Mozilla ent­wi­ckelt, um gra­fi­sche UI-Elemente, wie klei­ne Widgets oder gan­ze Fenster in Form brin­gen zu kön­nen, ohne ein kon­kre­tes Design fest­le­gen zu müs­sen. Das hört sich im ers­ten Moment selt­sam an, doch tat­säch­lich steht bei der Benutzung von XUL die Trennung von Layout und Design im Fokus. Mit die­ser Trennung kann der Entwickler dem Benutzer ermög­li­chen, sei­ne Software ganz ein­fach mit eige­nen Themes zu ver­se­hen. Für das Rendering der XUL-Oberflächen wird die Mozilla Gecko-Engine ver­wen­det. 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ür­lich auf der Hand.

XUL stand Pate für die Flexbox.

Die Vorgeschichte

Das tief­ge­hen­de Verständnis der Herkunft von Flexbox ist inso­fern wich­tig, als das es hilft, zu ver­ste­hen, 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 bis­he­ri­gen Boxmodellen beschrie­ben. Es soll das her­kömm­li­che Boxmodell nicht ablö­sen, son­dern ein neu­es Einsatzgebiet abde­cken. Die Herkunft aus der Widget-Programmierung deu­tet dar­über­hin­aus an, wo die­ses Einsatzgebiet genau liegt. Obwohl man mit dem Flexbox-Modul auch sehr bequem gan­ze Seiten-Layouts ver­wirk­li­chen könn­te, kom­men des­sen Stärken eher bei den klei­ne­ren UI-Elementen, ins­be­son­de­re bei Formularen zum Tragen.

Bevor wir gleich zum inter­es­san­ten Teil kom­men, sei hier noch aus­drück­lich dar­auf hin­ge­wie­sen, dass es sich bei der bis­he­ri­gen Spezifikation um eine frü­he Version, einen so genann­ten Working Draft, han­delt. Das Grundprinzip wird sich höchst­wahr­schein­lich nicht mehr ändern, jedoch könn­te es pas­sie­ren, dass eini­ge Eigenschaften einen ande­ren, prä­zi­se­ren Namen bekom­men oder man­che Details aus­ge­bes­sert wer­den.

Das Grundprinzip von Flexbox

Damit wir uns auf das Wesentliche, also das CSS kon­zen­trie­ren kön­nen, wer­den alle fol­gen­den Regeln auf die­se HTML-Struktur bezo­gen.

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

Und damit man über­haupt etwas sieht, wird fol­gen­des CSS als Grund-Styling vor­aus­ge­setzt. Im Laufe des Artikels wer­den diver­se Auszeichnungen, die man hier sieht, über­schrie­ben wer­den.

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

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

#eins {
	background: red;
}

#zwei {
	background: green;
}

#drei {
	background: blue;
}

Das bis­he­ri­ge Boxmodell kennt – wir unter­schla­gen hier der Einfachheit hal­ber alle kom­ple­xe­ren Formen – drei Arten von Elementen: blocks, inli­nes und inli­ne-blocks. Blocks ord­nen sich unter­ein­an­der an und sind mit margin und padding sty­lebar. Inlines ver­lau­fen neben­ein­an­der und bre­chen nur bei zu wenig hori­zon­ta­lem Raum um. Inline-Blocks sind eine Mischung aus bei­dem. Flexbox fügt dem bis­he­ri­gen Arsenal an Layout-Typen einen wei­te­ren hin­zu. Mit display: box; macht man ein Element zu einer Box. Diese Box ver­hä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 fol­gen­dem Erscheinungsbild:

Wie man sieht, wer­den die drei Blöcke in der Horizontalen neben­ein­an­der plat­ziert. Bis jetzt ist hier noch nichts fle­xi­bel, doch von fle­xi­bel steht ja auch noch nichts in unse­rem Stylesheet. Erst mit dem Attribut box-flex, das wir auf eines, meh­re­re oder alle Kind-Elemente anwen­den, kommt Elastizität ins Spiel. Anhand zwei­er 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, wel­che das Element über die gesam­te Fläche aus­dehnt (dazu spä­ter mehr). Hat nur einer der drei Blöcke eine sol­che “Feder”, nimmt die­ser den gesam­ten übri­gen Platz ein. Gibt es meh­re­re die­ser Blöcke mit Federn, müs­sen die­se sich den Platz tei­len. Die Aufteilung berech­net sich anteil­haft nach dem jewei­li­gen Box-Flex-Index. Je höher der Wert ist, den man der box-flex-Eigenschaft eines Elements zuweist, des­to mehr Raum nimmt das Element in Anspruch – des­to stär­ker ist die Spannfeder, um bei die­sem Bild zu blei­ben.

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

Hier nimmt das zwei­te Element genau sie­ben Achtel des rest­li­chen Raums zusätz­lich ein, Block Eins nur ein Achtel. Die genaue Verteilung berech­net sich näm­lich ver­hält­nis­mä­ßig zwi­schen 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 rela­tiv, bezie­hen sich jedoch nur auf die Breite des Elternelements. Andere Blöcke, die neben die­sem Element plat­ziert sind, wer­den nicht beach­tet. Box-Flex hin­ge­gen bezieht sich auf den ver­füg­ba­ren Platz und alle ande­ren Blöcke, die sich mit um den Kuchen ran­ken.

Und wie­der zurück zu dem Bild mit den Spannfedern: Eine star­ke Feder führt nicht unmit­tel­bar zu einer stär­ke­ren Ausdehnung, es müs­sen immer auch die Spannfedern aller ande­ren Elemente betrach­tet wer­den.

Das gan­ze Spiel ist sowohl in ver­ti­ka­ler als auch hori­zon­ta­ler Ausrichtung mög­lich. Der Eigenschaft box-orient kann man die vier Werte horizontal, vertical, inline-axis und block-axis zuwei­sen.

  • horizontal: Die Elemente wer­den neben­ein­an­der von links nach rechts ange­zeigt.
  • vertical: Die Elemente wer­den unter­ein­an­der von oben nach unten ange­zeigt.
  • inline-axis: Hängt von dem Attribut writing-mode ab. Normalerweise pro­vo­ziert inline-axis genau das glei­che Verhalten wie horizontal
  • block-axis: Hängt von dem Attribut writing-mode ab. Normalerweise pro­vo­ziert block-axis genau das glei­che Verhalten wie vertical

Die Optionen inline-axis und block-axis fin­den in der Realität wahr­schein­lich eher sel­ten ein Anwendungsgebiet, auf dem sie ihre Stärke voll aus­spie­len kön­nen.

Trotzdem soll­te man wis­sen, was die­se Schlüsselwörter bewir­ken: Das Attribut writing-mode, bezie­hungs­wei­se des­sen hori­zon­ta­le Komponente direction und des­sen ver­ti­ka­le Komponente block-progression, bestimmt die Leserichtung. So kann man etwa für den ara­bi­schen Raum ein­fach ein writing-mode: tb-rl notie­ren, und schon rich­ten sich die Zeichen in der Horizontalen von rechts nach links aus.

Per writing-mode las­sen sich Zeichen von rechts nach links anord­nen.

Inline-Axis und Block-Axis fol­gen nun auch die­ser Notation. Zwar wer­den die Stärken wie gesagt nur in den sel­tens­ten Fällen zum Tragen kom­men, den­noch kann man die bei­den Optionen stets den ande­ren bei­den vor­zie­hen. Man macht sich dadurch nichts kaputt, ist aber spä­ter deut­lich fle­xi­bler, wenn sich der Chef ent­schei­det, nun doch nach Nahost oder Asien zu expan­die­ren.

Richtung umkehren

Doch damit nicht genug. Will man jetzt noch zusätz­lich die Richtung, in der die Elemente aus­ge­rich­tet sind, umkeh­ren, hilft box-direction: reverse;. Die Eigenschaft könn­te dann inter­es­sant wer­den, wenn man auf­grund der Semantik im Markup etwas anders gewich­tet, als man es in der gra­fi­schen Ausgabe dar­stel­len möch­te. Wer die Ausrichtung nicht gleich kom­plett umkeh­ren, son­dern etwas prä­zi­ser vor­ge­hen möch­te, kann sich box-ordinal-group zuhil­fe neh­men. Weist man es meh­re­ren Kind-Elementen der Box mit einer belie­bi­gen Ganzzahl zu, wird das Element mit der nied­rigs­ten Zahl zuvor­derst ange­zeigt, das mit der höchs­ten als Letztes. Nach auf­stei­gen­den Zahlen also der Ausrichtung ent­lang.

#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 die­se Eigenschaft nicht zu, ist die box-ordinal-group auto­ma­tisch auf 1 gesetzt. Das ist mei­ner Meinung nach ein kri­ti­scher Punkt in der Spezifikation, denn wenn man ein Element an den Anfang der Reihe set­zen möch­te, soll­te das mög­lich sein, indem man nur die­ses eine Element ver­än­dert. Da aber “1” die Standardeinstellung und zugleich der höchst­mög­li­che Index ist, gestal­tet sich das unmög­lich. Es wäre noch mög­lich, einen Index von “0” zuzu­wei­sen, doch das führt der­zeit zu kata­stro­pha­len Ergebnissen bei den ver­schie­de­nen Browsern und in kei­nem Fall zu dem gewünsch­ten Ergebnis. Ich den­ke, an die­sem Punkt kann man noch eini­ge Änderungen in der Spezifikation erwar­ten.

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

Dass man ent­we­der zu wenig oder zu viel Platz in sei­ner Flexbox hat, kann nur dann pas­sie­ren, wenn kei­nem der Elemente box-flex zuge­wie­sen wur­de. Trotzdem ist es ganz hilf­reich zu wis­sen, was mit dem Platz pas­siert und wie man ihn hand­ha­ben kann.

Mit zu viel Platz geht man genau gleich um, wie sonst auch. Mit overflow kann man bestim­men, ob man die Elemente ein­fach über die Box hin­aus­lau­fen lässt, ob man sie ver­steckt oder ihnen eine Scrollbar gewährt.

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

box-pack für die Horizontale
start
Alle Elemente rich­ten sich am Anfang der Eltern-Box aus. Der ver­blei­ben­de Platz wird am Ende plat­ziert.
end
Genau das gegen­tei­li­ge Verhalten zu start.
jus­ti­fy
Zwischen jedes Element wird gleich viel Platz gescho­ben.
cen­ter
Die Elemente rücken zusam­men und der rest­li­che Platz wird links und rechts der Gruppe ver­teilt.
box-align für die Vertikale
start
Alle Elemente rich­ten sich am Anfang der Eltern-Box aus. Der ver­blei­ben­de Platz wird am Ende plat­ziert.
end
Genau das gegen­tei­li­ge Verhalten zu start.
cen­ter
Die Elemente rücken zusam­men und der rest­li­che Platz wird ober­halb und unter­halb der Gruppe ver­teilt.
base­li­ne
Die Elemente rich­ten sich nach ihrer typo­gra­fi­schen Grundlinie aus.
stretch
Der rest­li­che Raum wird den Höhen der Elemente gleich­mä­ßig hin­zu­ge­rech­net.

Browser-Support: Es sieht gut aus

Da die Spezifikation von Mozilla ange­trie­ben wird und die Gecko-Engine der­ar­ti­ge Layouts im Grunde schon seit Anfang ihres Bestehens inter­pre­tie­ren kann, ist es nicht ver­wun­der­lich, dass der Firefox ab Version 3.0.x das Modul größ­ten­teils unter­stützt. Auch die neue­ren Webkit-Browser las­sen einen prak­ti­schen Einsatz des Moduls zu. Mit Firefox, Safari und Chrome hat man also schon einen Großteil des Browser-Spektrums abge­deckt. Und wenn wir ein­mal ehr­lich sind, hät­te auch nie­mand erwar­tet, dass der Internet Explorer in sei­ner jet­zi­gen Form jemals eine der­art fort­schritt­li­che Technologie imple­men­tiert hät­te.

Zwar sind die Implementationen in Gecko und Webkit noch expe­ri­men­tell, das heißt es wer­den vor jeder Eigenschaft die Präfixe -moz- und -web­kit- gefor­dert, den­noch kann man es durch­aus schon wagen, mit dem Modul das ein oder ande­re pri­va­te Projekt zu gestal­ten.

(mm),

Markus Schlegel

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

4 Kommentare

  1. Hallo Markus, vie­len Dank für die­sen Artikel.
    Ich kämp­fe gera­de mit dem flex­box lay­out und den Unterschieden in den vre­schie­de­nen Browsern. Leider bekom­me ich das gewünsch­te Layout gera­de in Firefox nicht hin. Könntest Du Dir viel­leicht das Problem anschau­en: http://stackoverflow.com/questions/15008727/mozilla-flexbox-behavior-different-to-webkit-and-ie

    Danke im Voraus
    Grüße
    Alex

  2. Demoseite wae­re auf jeden fall prak­tisch damit man sich das mal am leben­den objekt mit ver­schie­de­nen brow­sern anse­hen kann.

  3. Man darf gespannt sein, wann der “gro­ße” IE sich die­sen Modelles annimmt.

    Ansonsten sehr schö­ner Artikel.

  4. Sehr inter­es­sant und prak­tisch. Vielen Dank für den Artikel, Markus.

Schreibe einen Kommentar

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