Flex-Box enschlüs­selt

Will man Ele­men­te auf eine Web-Sei­te hori­zon­tal oder ver­ti­kal anord­nen und aus­rich­ten, galt in der html-Urzeit die Tabel­le als Mit­tel der Wahl. Das kann aber schnell unüber­sicht­lich wer­den, beson­ders wenn man mehr oder weni­ger schmut­zi­ge Tricks anwen­den muss, um ein bestimm­tes Ver­hal­ten zu erzwin­gen. Gera­de die Rea­li­sie­rung von Respon­si­ve Designs, also Sei­ten, die sich der Geo­me­trie und Grö­ße der Betrach­tungs­ge­rä­te anpas­sen, ist damit nur schlecht möglich.

Die moder­ne­re Alter­na­ti­ve sind Flex-Boxen, die eine Viel­zahl der sonst nur mit Tricks erreich­ba­ren Eigen­schaf­ten bereits besit­zen. Lei­der ist das Sys­tem gera­de zu Beginn nicht gera­de intui­tiv zu ver­ste­hen, wes­we­gen man­cher davor zurück­schreckt. Daher die­ses klei­ne Anlei­tung, die den Ein­stieg hof­fent­lich etwas erleichtert.

Start mit „flex”

Flex-Boxen die­nen dazu, Ele­men­te in Zei­len oder Spal­ten nach gewis­sen Regeln anzu­ord­nen, so dass sie sich bei einer Ände­rung der Grö­ße der Gesamt­sei­te fle­xi­bel dar­an anpassen.

Als Bei­spiel soll fol­gen­de ein­fa­che Sei­te die­nen, die im Ele­ment div.umschlag drei Textab­sät­ze mit Über­schrif­ten in jeweils einem div.inhalt Block enthält:

<h1>Flex-Box Beispiel 1</h1>
<div class="umschlag">
  <div class="inhalt"><h2>Erster Eintrag</h2>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
  </div>
  <div class="inhalt"><h2>Zweiter Eintrag</h2>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
  </div>
  <div class="inhalt"><h2>Dritter Eintrag</h2>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
  </div>
</div>

Das Design sieht damit sehr schlicht so aus:

Will man die ein­zel­nen Absät­ze in einem mehr­spal­ti­gen Satz anord­nen, wür­de es mit html-Bord­mit­tel schwie­rig. Flex-Boxen ver­ein­fa­chen die­se Auf­ga­be sehr.

Das über­ge­ord­ne­te Ele­ment div.umschlag erhält ein­fach als display Attri­but das Schlüs­sel­wort flex:

<style>
.umschlag {
  display: flex;
}
</style>

Das macht div.umschlag zum Flex-Con­tai­ner und die div.inhalt Blö­cke zu Flex-Ele­men­ten. Das Stan­dard-Ver­hal­ten der Flex-Box ord­net alle Ele­men­te in der Box Neben­ein­an­der in iden­ti­scher Grö­ße an:

Erstaun­lich, was die­se klei­ne Ein­trag bewirkt, oder?

Will man an dem Stan­dard-Ver­hal­ten etwas ändern, soll­te man sich aller­dings etwas Theo­rie aneig­nen, um zu wis­sen, was man tut.

Das Flex Modell

In dem unten in den Quel­len ange­ge­be­nen Mozil­la-Arti­kel sind die wich­tigs­ten Begrif­fe des Flex-Modells in einer anschau­li­chen Gra­fik dargestellt.

In dem Eltern­ele­men, genannt „Flex-Con­tai­ner”, sind alle „Flex-Ele­men­te” an zwei Ach­sen ange­ord­net. Ent­lang der Haupt­ach­se („main axis”) sind die Flex-Ele­men­te auf­ge­reiht. Der Beginn der Ach­se ist „main start”, das Ende „main end” und die Distanz dazwi­schen die „main size”.

Senk­recht dazu ver­läuft die Quer­ach­se („cross axis”) von „cross start” bis „cross end”; die Ent­fer­nung dazwi­schen ist die „cross size”.

Aus­rich­tung

Ob die Ele­men­te hori­zon­tal oder ver­ti­kal ange­ord­net wer­den sol­len, lässt sich mit dem Attri­but „flex-direc­tion” fest­le­gen. Der Stan­dard­wert ist

flex-direction: row;

und ord­net die Ele­men­te hori­zon­tal in einer Zei­le an. Der ande­re Wert

flex-direction: column;

ord­net die Ele­men­te erwar­tungs­ge­mäß ver­ti­kal in einer Spal­te an.

Umbrü­che

Bei sehr vie­len Flex-Ele­men­ten kann der Platz auf der Zei­le schon mal knapp werden:

Unschön, aber mit dem Attri­but „flex-wrap” lässt sich die Zei­le umbre­chen und auf meh­re­re aufteilen.

flex-wrap: wrap;

Die Brei­te der ein­zel­nen Ele­men­te muss bei den css-Eigen­schaf­ten der Ele­men­te mit der „flex” Eigen­schaft ange­ge­ben wer­den, also z.B.

.inhalt {
  flex: 200px;
}

Dann wer­den die Ele­men­te mit einer Brei­te von 200px in einer Zei­le auf­ge­reiht. Reicht der Platz nicht mehr, wird das nächs­te Ele­ment in die fol­gen­de Zei­le verschoben.

Schon bes­ser. Wenn man jetzt übri­gens die Brei­te des Brow­ser-Fens­ter ver­klei­nert, wer­den die Flex-Ele­men­te ent­spre­chend ange­passt und ent­spre­chend der Brei­te umgebrochen:

Einen Nach­teil von Flex-Boxen sieht man übri­gens am unte­ren Rand: die Zei­len sind unab­hän­gig von­ein­an­der. In jeder Zei­le wird der hori­zon­ta­le Platz sepa­rat nach den Regeln der Box auf­ge­teilt. Sind wie in der letz­ten Zei­le weni­ger Ele­men­te auf der Zei­le, erhal­ten sie ent­spre­chend mehr Platz. Ein stren­ges Ras­ter lässt sich bes­ser mit der Grid-Box erzeugen.

Die Attri­bu­te „flex-direc­tion” und „flex-wrap” kann man auch als Attri­but „flex-flow” zusam­men­fas­sen:

flex-flow: row wrap;

Fle­xi­ble Größe

Bis jetzt war auf jeder Zei­le jedes Flex-Ele­ment gleich breit. Will man unter­schied­li­che Brei­ten erzeu­gen, funk­tio­niert das eben­falls mit dem „flex” Attri­but der Flex-Ele­men­te. Statt der oben benutz­ten abso­lu­ten Brei­te gibt man dann eine ein­heits­lo­se Ver­hält­nis­zahl an:

.inhalt {
  flex: 1;
}

Die­se Defi­ni­ti­on gilt für alle Flex-Ele­men­te und wür­de damit alle Ele­men­te wie­der gleich groß dar­stel­len. Soll ein Ele­ment eine ande­re Grö­ße bekom­men, muss für die­ses Ele­ment ein abwei­chen­der flex Wert defi­niert werden:

.inhalt:last-child {
  flex: 2;
}

Damit bekommt das letz­te Flex-Ele­ment die dop­pel­te Breite:

Zusätz­lich kann auch eine mini­ma­le Brei­te defi­niert werden:

.inhalt {
  flex: 1 200px;
}
.inhalt:last-child {
  flex: 2 200px;
}

Damit bekommt jedes Ele­ment zunächst eine Brei­te von 200px. Der übri­ge Platz wird ent­spre­chend des Ver­hält­nis­ses der flex-Zah­len ver­teilt. Das führt zu einer leicht ver­än­der­ten Darstellung:

Wach­sen und Schrumpfen

Mit dem kom­bi­nier­ten „flex” Attri­but kann man drei Eigen­schaf­ten gleich­zei­tig ein­stel­len: flex-grow, flex-shrink und flex-basis:

  • flex-grow ist die ein­hei­ten­lo­se Ver­hält­nis­zahl, die die rela­ti­ve Grö­ße des Ele­ments im Ver­hält­nis zu ande­ren Ele­men­ten angibt
  • flex-shrink ist eine wei­te­re ein­hei­ten­lo­se Ver­hält­nis­zahl, die angibt, wie stark ein Ele­ment ver­klei­nert wird, wenn es grö­ßer als der über­ge­ord­ne­te Con­tai­ner wird.
  • flex-basis legt die Min­dest­grö­ße des Ele­ments fest.

Fol­gen­de Anga­ben sind also identisch:

flex 1 1 200px;

und

flex-grow 1;
flex-shrink 1;
flex-basis: 200px;

Aus­rich­tung

Flex-Ele­men­te kön­nen mit den Attri­bu­ten „ali­gn-items” und „jus­ti­fy-con­tent” hori­zon­tal und ver­ti­kal aus­ge­rich­tet werden.

  • align-items defi­niert im Con­tai­ner die Anord­nung aller Ele­men­te auf der Querachse: 
    • normal oder stretch
      Die Ele­men­te wer­den ent­lang der Quer­ach­se so gestreckt, dass sie den Platz ausfüllen.
    • center
      Die Ele­men­te behal­ten ihre Grö­ße bei und wer­den ent­lang der Quer­ach­se zentriert.
    • start, end
      Die Ele­men­te wer­den am den Start bzw. an das Ende der Quer­ach­se ausgerichtet.
  • Die Anord­nung ein­zel­ner Ele­men­te kann mit „ali­gn-self” im Flex-Ele­ment selbst über­schrie­ben werden.
  • justify-content defi­niert die Anord­nung der Ele­men­te auf der Hauptachse: 
    • normal oder start oder left
      Rich­tet die Ele­men­te am Start der Haupt­ach­se aus.
    • end oder flex-end oder right
      Rich­tet die Ele­men­te am Ende der Haupt­ach­se aus.
    • center
      Rich­tet die Ele­men­te mit­tig aus.
    • space-between
      Rich­tet das ers­te Ele­ment links, das letz­te Ele­ment rechts und alle dazwi­schen mit­tig mit gleich­mä­ßi­gem Abstand aus.
    • space-around
      Rich­tet die Ele­men­te mit­tig mit gleich­mä­ßi­gem Abstand (auch am Start und Ende) aus.

Hier ein ein­fa­ches Beispiel:

<style>
div {
  height: 100px;
  border: 1px solid black;
  display: flex;
  align-items: <align>;
  justify-content: <justify>;
}
button {
  width: 10%;
}
</style>
<div>
  <button>E1</button>
  <button>E2</button>
  <button>E3</button>
  <button>E4</button>
</div>

Mit den unter­schied­li­chen Wer­ten für ali­gn und jus­ti­fy sieht das so aus:

Umsor­tie­ren

Die Rei­hen­fol­ge der Ele­men­te kann mit „order” ver­än­dert wer­den. Dadurch wird ein „order value” gesetzt, nach dem die Flex-Ele­men­te auf­stei­gend sor­tiert wer­den. Zu Beginn haben alle Ele­men­te das „order value” Null.

Bei glei­chem „order value” wer­den die Ele­men­te nach der Rei­hen­fol­ge im html-Code sor­tiert. Auch nega­ti­ve Wer­te sind für das „order value” mög­lich, um ein Ele­ment vor allen ande­ren mit dem Stan­dard­wert 0 erschei­nen zu lassen.

Die Sor­tie­rung im Flex-Con­tai­ner ändert aller­dings nichts an der Tab-Rei­hen­fol­ge, also an der Rei­hen­fol­ge, in der Ele­men­te mit der Tab-Tas­te durch­lau­fen werden.

Ver­schach­tel­te Flex-Boxen

Flex-Boxen kön­nen ver­schach­telt wer­den. Inner­halb einer Flex-Box kön­nen wei­te­re plat­ziert wer­den, um kom­pli­zier­te Struk­tu­ren zu erzeu­gen. Das geschieht, indem man einem Flex-Ele­ment wie­der die „dis­play” Eigen­schaft „flex” zuweist. inner­halb die­ser Toch­ter-Box gel­ten dann nur die Defi­ni­tio­nen die­ses Tochter-Containers.

Flex-Boxen haben Eigen­schaf­ten, die die dyna­mi­sche Anord­nung von Ele­men­ten inner­halb eines umge­ben­den Con­tai­ners sehr ver­ein­fa­chen kön­nen. Wer es als Nach­teil emp­fin­det, dass Brei­te und Höhe der Flex-Ele­men­te nicht immer ein­heit­lich ist, soll­te einen Blick auf die Schwes­ter der Flex-Box, das Grid-Lay­out werfen.


Quel­len:

Schreibe einen Kommentar

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

2 × 4 =