Herzlich willkommen zum SELF-Treffen 2026
vom 24.04. – 26.04.2026 in Halle (Saale)

CSS/Tutorials/Flexbox/Mehrspaltenlayout

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

In diesem Abschlusskapitel zeigen wir, wie man mit Flexbox eine Webseite mit mehreren Elementen erstellt, die sich problemlos an alle Viewports anpasst.

Grundstruktur

Als Grundstruktur verwenden wir unsere Webseite aus dem HTML-Tutorial:

HTML5-Seite mit Grundstruktur ansehen …
<body>
  <header>
    <!--- Kopfzeile --->
  </header>
  
  <main>
     <!--- Inhalt --->
  </main>

  <aside>
    <!---weiterführende Informationen --->
  </aside>

  <footer>
    <!--- Fußzeile --->
  </footer>
</body>

Responsivität

Damit die Webseite sowohl in einem schmalen Browserfenster des Desktop-PCs als auch auf dem Smartphone oder Laptop wunschgemäß dargestellt wird, muss man mithilfe eines meta-Elements dafür sorgen, dass sich die Seite an den Viewport anpasst.

Notiere dazu folgende Zeile im head der Seite:

 <meta name="viewport" content="width=device-width, initial-scale=1.0">

Für weitere Erklärungen siehe HTML/Elemente/meta#Viewport einstellen.


Maximale Breite festlegen

Textzeilen, die sich über die gesamte Breite eines großen 4k-Monitors erstrecken, sind nur schwer lesbar.

Um die Breite des Inhaltsbereichs zu begrenzen und zu lange Textzeilen zu vermeiden, wurde dem body der Beispielseite eine maximale Breite zugewiesen.

Seite mit flexibler Breite
body {
    margin: 0 auto;
    max-width: 60em;
}

Mit margin: 0 auto wird die Seite zentriert.

Für <body> ist die CSS-Eigenschaft max-width: 60em; angegeben, um der Seite eine maximale Breite zu geben. Bei kleineren Viewports verringert sich die Breite, sodass die Seite nie breiter als der Bildschirm wird.


Empfehlung:
Verwende für dein Layout keine festen Breitenangaben in Pixel. Wenn ein Benutzer die Schriftgröße im Browser ändert, wird im schlimmsten Fall das Layout zerschossen.
Breitenangaben in relativen em passen deine Webseite flexibel an die Schriftgröße an!

ein flexibler Container

Um ein flexibles Layout zu verwenden, müssen wir dem flexiblen Container-Element body ein display: flex; geben. Jetzt werden alle direkten Kind-Elemente zu Flex-Items. Diese Elemente können (wie auch hier im Beispiel) zu verschiedenen Typen gehören.

Empfehlung: Da nur die direkten Kind-Elemente ein flexibles Layout haben, empfiehlt es sich, eine zu große Verschachtelung von div-Elementen (Div-Suppe) von vorne herein zu vermeiden. Es ist mit Flexbox auch nicht mehr nötig.

Mit flex-direction kann man festlegen, ob die Flex-Items in Reihen oder Spalten angelegt werden sollen. Hier wird der Standardwert row der horizontalen Anordnung übernommen. Mit flex-flow: wrap bestimmst du, dass Elemente in mehreren Reihen dargestellt werden, wenn sie (zusammen) die verfügbare Breite überschreiten.

HTML5-Seite mit Grundstruktur ansehen …
body{
  display: flex;
  flex-flow: row wrap;
}

header, nav, footer {
  flex: 1 100%;
}

article {
  flex: 3 1 0%;
}

aside {
  flex: 1 1 0%;
}

Mit der Eigenschaft Flex-Items#flex|flex gibst du den Elementen relative Größenangaben. Header, Navigation und Fußzeile erstrecken sich mit der Angabe 100% über die gesamte verfügbare Breite. Interessanter wird es beim Artikel und den beiden Asides: Mit dem flex-grow-Faktor bestimmst du, dass der Artikel dreimal so breit wie die Breite der aside-Boxen sein soll. Die genauen Werte berechnet der Browser dann automatisch!

Beachte: CSS-Einstellungen wie position, float oder clear sind im flexiblen Layout nicht nötig. Angegebene Werte werden ignoriert.


vertikale Zentrierung

Hast du im vorigen Beispiel gemerkt, dass sich die Höhe der article und aside-Boxen automatisch an der größten Höhe ausrichtet? Dies kann man durch Angabe einer festen Höhe verhindern:

HTML5-Seite mit Grundstruktur ansehen …
#news {
  height: 120px;
  align-self: center;
}

Durch die Angabe der Eigenschaft align-self gibst du dem News-Container ohne weitere Einstellungen eine vertikale Zentrierung.


horizontale Navigation

Das flexible Layout beeinflusst nur die direkten Kind-Elemente. Für eine horizontale Navigation müssen nun der header selbst und nav ul zu flexiblen Containern werden.

HTML5-Seite mit Grundstruktur ansehen …
header {
  display: flex;
  flex-flow: row wrap;  
}

header * {
  flex: 1 1 0%;
}

header img {
  flex: 0 0 400px;
  margin-right: 50px;
}  

header nav {
  flex: 1 1 100%;
}

nav ul {
  display: flex; 
  justify-content: space-around;
  flex-direction: row;
}

Das Logo bekommt eine feste Breite von flex: 0 0 400px;, damit es nicht verzerrt dargestellt wird. Anstelle des sonst üblichen display: inline-block; wird die horizontale Anordnung durch flex-flow festgelegt.


Das fertige Layout

Wir erstellen nach dem Grundsatz Mobile First eine Grundstruktur für mobile Geräte. Diese sieht auch auf breiteren Bildschirmen ansprechend, wenn auch einfach aus:


Mobile first

Für kleinere Viewports setzen wir nun die Breiten für alle Blöcke und für die Navigationslinks auf 100%:

HTML5-Seite mit Grundstruktur ansehen …
/* Mobile first - alle Dokument-Blöcke bekommen 100% Breite */  

header, nav, article, aside, footer {
  flex: 1 100%;
}
  
header {. 


  display: flex;
  flex-flow: row wrap;
}
  
header * {
  flex: 1 1 0%;
}

header img {
  flex: 0 0 100px;
  height: 45px;
}  

header nav {
  flex: 1 1 100%;
}
  
nav ul {
  display: flex;  
  flex-direction: column;
}

nav li {
  margin: 1.3em 0;
  flex: 1 1 100%;
}

Der einzige Unterschied findet sich in der Anordnung: Während die Inhaltsblöcke mit flex-flow: row wrap; die ganze Breite ausfüllen und dann umbrechen, wird die Navigation mit flex-direction: column; in einer vertikalen Säule dargestellt – die Wirkung ist aber immer die gleiche.

Verschiedene Darstellungen je nach Viewport

Viewports mit größerer Auflösung bekommen mit media-queries andere Einstellungen zugewiesen:

HTML5-Seite mit Grundstruktur ansehen …
/* Smart Phones und Tablets mit mittlerer Auflösung */
@media all and (min-width: 35em) {
	
  header img {
    flex: 0 0 200px;
    height: 90px;
  }

  nav ul {
    flex-direction: row;
  }
  
  nav li {
    flex: 1 1 0%;
  }	

  /* durch auto werden die beiden asides in eine Zeile gesetzt */
  aside { 
    flex: 1 auto;
  }

  article { 
    order: 2; 
  }
  #news { 
    order: 3; 
  }
  aside { 
    flex: 1 1 auto;
    order: 4; 
  }
  footer {
    order: 5;
  }
}

/* Smart Phones und Tablets mit mittlerer Auflösung */

@media all and (min-width: 35em) {
	header img {
		margin-right: 50px;
	}
	nav ul {
		flex-direction: row;
	}
	nav li {
		margin: 0 10px;
		flex: 1 1 0%;
	}
	article {
		order: 2;
	}
	#news {
		flex: 1 auto;
		order: 3;
	}
	aside {
		/* durch auto werden die beiden asides in eine Zeile gesetzt */
		flex: 1 auto;
		order: 4;
	}
	footer {
		order: 5;
	}
}

/* Viewports mit großer Auflösung */
@media all and (min-width: 50em) {
/* article wird 2.5x so breit wie die beiden asides */
  article {                        
    order: 3;	
    flex: 5 1 0%;
  }

  aside {
    flex: 2 1 0%;
  }
  #news {
    flex: 2 1 0%;
    order: 2;
    align-self: center;
    height: 120px;  
  }
}

Ab 35em Breite wird die Navigation mittels der Eigenschaft flex-direction über die werte column und dann row nicht mehr in einer vertikalen Spalte, sondern in einer horizontalen Reihe dargestellt. Die einzelnen Listenpunkte werden automatisch auf die verfügbare Breite verteilt.

Abweichend vom Beispiel 1 wird der Inhaltsbereich nun nur 2,5 mal so breit wie die aside-Boxen. Dafür geben wir ihm einen flex-grow-Faktor flex: 5 1 0; gegenüber dem kleineren Faktor: flex: 2 1 0; für die Aside-Boxen.

aside-Boxen am Rand

HTML5-Seite mit Grundstruktur ansehen …
/* Mobile first - alle Dokument-Blöcke bekommen 100% Breite */  

header, nav, article, aside, footer {
  flex: 1 100%;
}

/* Smart Phones und Tablets mit mittlerer Auflösung */
@media all and (min-width: 35em) {
	
  /* durch auto werden die beiden asides in eine Zeile gesetzt */
  #news { 
    order: 3; 
  }

  aside { 
    flex: 1 1 auto;
    order: 4; 
  }
}

/* Viewports mit großer Auflösung */
@media all and (min-width: 50em) {
/* article wird 2.5x so breit wie die beiden asides */
  article {                        
    order: 3;	
    flex: 5 1 0%;
  }

  aside {
    flex: 2 1 0%;
  }
  #news {
    order: 2;
    align-self: center;
    height: 120px;  
  }
}

Ändere die Anzeigebreite deines Browsers (z. B. mit <shift>+<strg>+<m> im Firefox) und beobachte das Verhalten der beiden aside-Boxen. Bei kleinen Viewports nehmen die Boxen die gesamte Breite ein. Steigt die Breite über 35em, werden die beiden Boxen nebeneinander angeordnet. Dabei wird die Reihenfolge der Darstellung gegenüber dem Elementfluss mit order verändert.

Beachte: Wenn du mit order eine abweichende Reihenfolge festlegst, müssen alle nachfolgenden Elemente (wie hier der footer) ebenfalls eine festgelegte Reihenfolge bekommen, da sie sonst an den Anfang rutschen.

Bei Auflösungen von 50em und höher wird die ursprüngliche Reihenfolge wieder hergestellt. Dafür bekommt die #News-Box auf der linken Seite jetzt eine feste Höhe und wird vertikal zentriert.

Wie geht's weiter?

Mit diesem flexiblen Aufbau bist du für die Zukunft gerüstet.

Weitere Beispiele, in denen Flexbox eingesetzt wird:


Fertige Layouts mit Flexbox:

  • Ihr Anwalt
    Vorschau-02.png
  • Man with Hat
    Design06-Vorschau.png
  • CSS-Garten
    Vorschau-garten.gif


Neben Flexbox gibt es das neue Grid Layout mit dem du Elemente nicht nur entlang einer Achse, sondern zweidimensional frei und flexibel gestalten kannst.


Weblinks

Ein Dropdown-Menü mit Flexbox