Grid Layout

Ein grid (englisch für Gitter, Gestaltungsraster)) ist ein Ordnungssystem in der visuellen Kommunikation, das als Hilfskonstruktion die Organisation von grafischen Elementen auf einer Fläche oder in einem Raum erleichtert.

Im Webdesign waren das früher Tabellen-Layout der 90er und die Entwicklung von „CSS-Frameworks“ wie bootstrap Versuche, Webseiten übersichtlich mit Rastern zu gestalten. Allerdings benötigten diese Ansätze eine Vielzahl von zusätzlichen HTML-Elementen, die das Markup an sich unübersichtlich werden ließen und das Prinzip der Trennung von Inhalt, Präsentation und Verhalten missachteten.

Mit dem CSS Grid Layout Modul ist nun endlich eine Lösung gefunden worden. Teilweise ist es sogar möglich, alle CSS-Festlegungen im Grid-Container vorzunehmen, was responsive Flexibilität und spätere Änderungen sehr erleichtert.

Dieses Kapitel stellt mehrspaltige Allround-Layouts vor, die Seitenelemente nach dem Grundsatz „Mobile first!“ auf kleinen Viewports untereinander, bei breiteren Bildschirmen in mehreren Spalten nebeneinander angeordnet werden.

Holy-Grail-Layout

Das Holy-Grail-Layout ist ein Webseiten-Layout, das mehrere, trotz unterschiedlichen Inhalts gleich hohe Spalten hat. Es wird häufig gewünscht und implementiert, konnte aber viele Jahre lang mit damals verfügbarem CSS nur mit vielen Hacks, die alle Nachteile hatten, realisiert werden. Aus diesem Grund wurde das Finden einer optimalen Implementierung mit der Suche nach dem schwer fassbaren Heiligen Gral verglichen.

body {
   display: grid;
   gap: 0.5em;
}
 
@media (min-width: 45em) { 
   /* Breite beträgt mindestens 45em */ 
   body {
      grid-template-columns: 1fr 3fr 1fr;	
      grid-template-rows: auto 1fr 100px;
   }
}
 
header,footer {
	grid-column: 1 / -1;
}

Das Grid Layout erstellt für den body ein Raster mit 3 Spalten und 3 Reihen. Diese erhalten zum Teil feste, zum Teil flexible Höhen und Breiten. So bestehen die Werte für grid-template-columns nur aus Bruchteilen (fr - der verfügbare Platz verteilt sich automatisch. Die Höhe richtet sich in der ersten Reihe nach dem Inhalt (auto), in der letzten beträgt sie 100px Höhe - die mittlere Reihe nimmt mit der Festlegung 1fr wieder den verfügbaren Rest ein.

Nur header und footer werden mit grid-column von der ersten (1) bis zur letzen Randlinie (-1) positioniert. Im 3-Spalten-Layout bei breiten Viewports erstrecken Sie sich über die gesamte Breite.

Zweispaltiges Layout

body {
   display: grid;
   gap: 0.5em;
}
 
@media (min-width: 30em) { 
   /* Breite beträgt mindestens 30em */ 
   body {
      grid-template-columns: 1fr 3fr;	
      grid-template-rows: auto 1fr 100px;
   }
}
 
header,footer {
   grid-column: 1 / -1;
}

Medien im Grid-Layout

Das Media-Objekt ist ein Entwurfsmuster mit einer Grafik links und heading sowie Text rechts daneben.

<ul class="media">
  <li>
    <img src="Frühling.png" alt="Bild einer Narzisse, Quelle Wikipedia">
    <h3>Frühling</h3>
    <p>Endlich wird es wieder ein bisschen sonniger und wärmer. 
       Wer jetzt spazieren geht, sieht schon die ersten grünen Knospen sprießen.
     </p>
     <footer>
    optionaler Footer 
     </footer>  
  </li>
</ul>
Das Media-Objekt besteht aus einem Listenelement, das ein Bild, eine Überschrift sowie einen Textabsatz und optional einen Footer enthält.
.media li {
  display: grid;
  grid-template-columns: 7em 1fr;
  grid-template-rows: 2em 3em;
  gap: 1em;
  margin-bottom: 1em;
}
 
.media li>img {
  grid-row: 1 / 3;
  width: 6em;
}

Längenangabe

Viele Tutorials über Grid Layout verwenden für die Spaltenbreiten Längenangaben in festen Pixelwerten. Dies ist möglich; verhindert aber einen entscheidenen Vorteil des Grid Layout Moduls: anstelle des Entwicklers legt der Browser des Benutzers die Maße anhand des verfügbaren Platzes fest.

Anstelle des Werts auto, der dem Inhalt den minimal benötigten Platz zuweist, können Sie auch eigene Zuweisungen in Form von Längenangaben oder Bruchteilen angeben. Schon bei Flexbox konnte man auf die Berechnung von Prozent-Werten verzichten und der flex-Eigenschaft eine Zahl als Anteil an der verfügbaren Breite zuordnen, aus deren Gesamtwerten dann die verfügbare Breite vom Browser berechnet wurde. Im Grid Layout gibt es hierfür die neue Einheit fr (fraction: engl. für Bruchteil).

Ändern Sie im obigen Beispiel die Werte für die Spalten auf:

 grid-template-columns: 1fr 1fr 1fr ;

Jede Spalte bekommt nun ein 1/3 der gesamten Breite.

repeat ()

Das „CSS-Framework“ Bootstrap besteht aus einem Raster mit 12 Spalten. Hier könnte man mit der repeat()-Funktion auf eine Angabe der Einzelwerte verzichten:

grid-template-columns: repeat(12, 1fr);

Die Kindelemente des Rasters verteilen sich auf 12 Spalten. Für unser Beispiel ist das aber noch nicht praktikabel, da die sechs direkten Kindelemente des Rasters jetzt alle nebeneinander und sehr schmal dargestellt werden

gap

Das Grid-Layout platziert die Grid-Streifen normalerweise direkt nebeneinander. Die frühere Methode, für Abstand zu sorgen, bestand aus dem Setzen von margin-Angaben, was aber zu störenden Rändern am Rand des Grids führen kann.

Die Eigenschaften column-gap und row-gap ermöglichen das Setzen von Spalten- und Zeilenabständen direkt im Grid. Sie können eine Längen- oder Prozentangabe verwenden, oder mit calc() berechnen. Um Spalten- und Zeilenabstand gleichzeitig zu setzen, gibt es die Shorthand-Eigenschaft gap.

Beispiel

Grid Items

Ein Grid Cointainer enthält Grid Items. Jeder Container hat zumindest ein Grid Item für jede Spalte. Für jede Zeile und Spalte kann man mehrere Grid Items zusammenfassen.

Beispiel:

<html>
<head></head>
<body>
 
<h1>A Five Items Grid Layout</h1>
 
<div class="grid-container">
  <div class="grid-item item1">1</div>
  <div class="grid-item item2">2</div>
  <div class="grid-item item3">3</div>  
  <div class="grid-item item4">4</div>
  <div class="grid-item item5">5</div>
</div>
 
<p>Direct child elements(s) of the grid container automatically becomes grid items.</p>
 
<p>Item 1, 2, and 5 are set to span multiple columns or rows.</p>
 
</body>
</html>
.grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr ;
  grid-template-rows: 1fr 1fr 1fr;
  gap: 10px;
  background-color: #2196F3;
  padding: 10px;
}
 
.grid-item {
  background-color: rgba(255, 255, 255, 0.8);
  text-align: center;
  padding: 20px;
  font-size: 30px;
}
 
.item1 {
  grid-column: 1 / span 2;
  grid-row: 1;
}
 
.item2 {
  grid-column: 3;
  grid-row: 1 / span 2;
}
 
.item5 {
  grid-column: 1 / span 3;
  grid-row: 3;
}

Responsive Grid-Layouts

Blockelemente wie Überschriften oder Absätze nehmen im Standardverhalten der Browser stets die verfügbare Breite ein. Mit der Einführung von CSS wurde es möglich, Positionierungen und Größenangaben auch außerhalb des Elementflusses festzulegen.

Dies ermöglichte einerseits ein pixelgenaues Layout, wurde andererseits bei einer Änderung des Viewports zum Bumerang, da sich Inhalte außerhalb des sichtbaren Bereichs oder unter anderen Elementen befanden oder durch overflow: hidden; abgeschnitten wurden. Media queries bieten hier eine Lösung, doch die immer wiederkehrende Frage nach den richtigen Breakpoints zeigt, dass aber auch dies nicht die einfachste Lösung ist.

Grid Layout beginnt wieder von vorne: Der verfügbare Raum wird aufgeteilt, weitere Inhalte werden innerhalb des Rasters in weiteren Reihen dargestellt und wandern so nach unten, wo man sie durch Scrollen erreichen kann.

Responsives Raster mit Media-Queries

body{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}
 
@media (min-width: 30em) { 
  body{
    grid-template-columns: repeat(3, 1fr);
}
 
@media (min-width: 50em) { 
  body{
    grid-template-columns: repeat(4, 1fr);
  }
}

Responsivität ohne Media queries

Im Folgenden soll gezeigt werden, wie Raster mit flexibler Spaltenanzahl angelegt werden, die sich auch ohne Media Queries responsiv an den Viewport anpassen

auto-fill

Bequemer als die Lösung mit media queries ist es allerdings, mittels des Schlüsselworts auto-fill den Browser die Anzahl der Spalten automatisch festlegen zu lassen:

body{
  display: grid;
  grid-template-columns: repeat(auto-fill, 20em);
}
 
article {
  grid-column: 1 / -1;
  grid-row: span 2;
}

In diesem Beispiel wurde die repeat()-Funktion verwendet, die nun über den ersten Parameter auto-fill so viele Spalten wie möglich erzeugt. Der zweite Parameter gibt die Breite der Spalten (20em) vor.

Das article-Element soll, wenn der Platz ausreicht, breiter werden.

minmax()

Damit der autoplacement-Algorithmus seine volle Wirkung entfalten kann, muss die Breite der Spalten flexibel sein. Bisher wurde dies bei fester Spaltenanzahl mit der Einheit fr erledigt. Nun sollen die Spalten eine feste Mindestgröße, aber auch keinen überschüssigen Raum in Form eines leeren Rands haben.

Voilà: Die minmax()-Funktion erlaubt es anstelle von festen oder relativen Längenangaben einen Mindest- und einen Maximalwert anzugeben: