CSS/Tutorials/Flexbox/Mehrspaltenlayout

Aus SELFHTML-Wiki
< CSS‎ | Tutorials‎ | Flexbox
Wechseln zu: Navigation, Suche

In diesem Abschlusskapitel lernen Sie, wie Sie mit Flexbox eine Webseite mit mehreren Elementen erstellen, 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, müssen Sie mithilfe eines meta-Elements dafür sorgen, dass sich die Seite an den Viewport anpasst.

Notieren Sie 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:
Verwenden sie für Ihr Layout keine festen Breitenangaben in Pixel. Wenn ein Benutzer die Schriftgröße im Browser ändert, wird im schlimmsten Fall Ihr Layout zerschossen.
Breitenangaben in relativen em passen Ihre 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 können Sie 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 bestimmen Sie, 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 geben Sie 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 bestimmen Sie, dass der Artikel dreimal so breit wie die Breite der aside-Boxen sein soll. Die genauen Werte berechnet der Browser dann automatisch!

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


vertikale Zentrierung

Haben Sie im vorigen Beispiel gemerkt, dass sich die Höhe der article und aside-Boxen automatisch an der größten Höhe ausrichtet? Dies können Sie 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 geben Sie 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;  
  }
}

Ändern sie die Anzeigebreite Ihres Browsers (z. B. mit <shift>+<strg>+<m> im Firefox) und beobachten Sie 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.

Beachten Sie: Wenn Sie mit order eine abweichende Reihenfolge festlegen, 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 sind Sie für die Zukunft gerüstet.

Weitere Beispiele, in denen Flexbox eingesetzt wird:


Fertige Layouts mit Flexbox:


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


Weblinks

Ein Dropdown-Menü mit Flexbox