Native CSS Grid Layouts ohne Framework – ein einfaches Beispiel

Für die nächste Ausgabe des t3n Magazin (Nr. 48) schreibe ich einen Artikel über CSS Grids… hier vorab ein kleiner Ausschnitt daraus.

Eine neue CSS Grid Layout Spezifikation gibt Webworkern nun die Möglichkeit eigene Grids nach den jeweiligen Anforderungen selbst zu definieren. Das ist nicht nur für Seitenlayouts, sondern auch für Modul-Layouts sehr nützlich. Aber zugegeben sind auch sehr viele neue Eigenschaften zu lernen, 17 neue Eigenschaften in Summe.

Nun wird sich der ein oder andere Entwickler fragen: „ok, aber was ist jetzt der Unterschied zu Flexbox“? Einige Entwickler nutzen bereits Flexbox anstatt „Floats“ als CSS-Technik für Grid-Layouts.

Wenn man Layouts wie gewohnt in 12 Spalten aufbaut und diesen Aufbau nicht verändert, sondern nur die unterliegende CSS-Technik, dann klingt das auch erstmal logisch und einfach Flexbox zu verwenden. Deshalb nutzt Bootstrap ab Version 4 auch Flexbox-Grids.

Was ist nun der Unterschied zwischen Flexbox und CSS Grids?

CSS Grids sind zweidimensional, Flexbox ist eindimensional. Flexbox-Grids sind bildlich gesprochen nur 1-zeilig (flex-wrap: wrap mal ignoriert), also Zelle für Zelle auf einer Zeile ohne Umbruch. Ein CSS Grid-Layout kann man über mehrere „Zeilen“ aufbauen. Man stelle sich vor, dass man ein einfaches Seitenlayout hat. Dort ist eine Spaltigkeit für header und footer festgelegt – dies kann man natürlich auch mit Flexbox abbilden, aber die Zellen haben untereinander keine Verbindung. Mit einem CSS Grid-Layout ist das anders, dort gibt es ein sogenanntes Grid-Template, das für den Bereich gilt.

Aber vielleicht mal ein einfaches Beispiel als Einstieg: ein 3-spaltiges „Komponenten-Layout“. Hier das visuelle Ergebnis, was wir mit CSS Grids aufbauen möchten:

Komponenten-Layout, 3-spaltiges Grid

Ein Komponentencontainer (.wrapper) und 4 Inhaltscontainer (.box)

<div class="wrapper">
  <div class="box a">.a</div>
  <div class="box b">.b</div>
  <div class="box c">.c</div>
  <div class="box d">.d</div>
</div>

Für diese Komponente fügen wir nun ein Grid-Layout hinzu.

Ein neuer Wert für die CSS-Display-Eigenschaft: `grid`:

/* grid layout, 3 columns */
.wrapper {
  display: grid; /* display: inline-grid;*/
  grid-template-columns: 1fr 1fr 1fr; /* 3 x 1 fraction */    
}

display: grid ist wie display: flex ein neuer Wert für die Display-Eigenschaft des Container-Elements. Alle direkten Kinder werden dann zu Grid-Elementen. Zu den neuen Layout-Eigenschaften bringt CSS Grids auch eine neue Maßeinheit mit. Gridgrößen können natürlich auch weiterhin mit allen vorhanden Maßeinheiten erstellt werden. Sowohl Prozent-, als auch Pixelwerte, als auch weitere Breiteneinheiten sind möglich. Grid-Zellengrößen können nun in ‚fr‘ (fraction) angegeben werden. Als Beispiel können drei gleich breite Spalten mit grid-template-columns: 1fr 1fr 1fr; erstellt werden. Ein 2-spaltiges Grid mit einer großen Haupt- und einer Marginalspalte im Verhältnis 2:1 erstellt man wie folgt: grid-template-columns: 2fr 1fr;1fr bedeutet 1 Teil, 2fr bedeutet 2 Teile der Gesamtbreite. Je Spalte wird je ein Wert getrennt mit Leerzeichen geschrieben. Für das letzte Beispiel könnte man auch grid-template-columns: 66.667% 33.334%; schreiben.

12 gleich breite Spalten, das klassische 12-spaltiges Layout?

Der Aufbau geht natürlich auch mit 12 gleichen Werten, aber der Einfachheit halber gibt es die repeat()-Funktion: grid-template-columns: repeat(12, 1fr); – 12 gleiche Spalten, quasi je 1/12 Spaltenbreite. Für zeilenweise Grids gibt es das Pendant grid-template-rows. Möchte man z.B., dass der Seitenheader und der -footer eine bestimmte Höhe haben, der Inhalt dazwischen aber flexibel ist, kann man auto als Höhe für den Hauptinhalt angeben, Beispiel: grid-template-rows: 10em auto 10em;, Seitenheader und -footer sind hier genau 10em hoch. Für unser Beispiel von oben machen wir für die Grid-Zeilen keine Größenvorgaben, dann sind die Gridzellen, wie bei Flexbox, alle gleich hoch und zwar so groß wie die größte Zelle der gesamten Zeile.

Positionierung im CSS-Grid

Historisch bedingt gibt es ähnlich wie bei Flexbox unterschiedliche Schreibweisen um Position und Größe einer Grid-Zelle festzulegen. Die unterschiedlichen Schreibweisen können aber in allen Browsern verwendet werden. Folgende Schreibweisen ergeben alle die gleiche Positionierung:

.a {
  /* starts at col pos 1, spans 2 cols */
  grid-column: 1 / span 2;
  /* starts at row pos 1, spans 1 row */
  grid-row: 1 / span 1;
}

.a {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;
}

.a {
  /* grid-column-start: 1 / grid-column-end: 3 */
  grid-column: 1 / 3;
  /* grid-row-start: 1 / grid-row-end: 2 */
  grid-row:    1 / 2;
}
Grid-Layout mit Positionierungslinien (Tracks)
Zwischenstand: Bereich .a ist zwei Spalten groß, Bereich .b rutscht automatisch in die nächste Spalte, .c auf die nächste Zeile

Die Eigenschaften grid-column/-row sind für die Positionierung der Zellen im Grid zuständig, wobei grid-column/-row die Kurzschreibweise für grid-column-start/-end (grid-row-start/-end) ist. Bei dieser Schreibweise gibt man die Startposition und die Endposition der Zelle an. Die alternative Schreibweise ist, dass man die Startposition angibt und nicht die Endposition, sondern über wie viele Spalten sich die Grid-Zelle aufspannen soll. Die Angabe lautet dabei span anzahl, also hier im Beispiel span 2, zwei Spalten vom Grid-Layout nimmt die Gridzelle ein.

.a {
  grid-column: 1 / span 2;
  grid-row: 1 / span 1;
}
.b {
  grid-column: 3 / span 1;
  grid-row: 1 / span 2;
}

Dies ist ebenso für das Überspannen von Zeilen möglich – grid-row: 1 / span 2; – überspannt zwei Zeilen beginnend ab Zeile 1. Der Default-Fall ist, dass eine Zelle automatisch platziert wird und 1 Spalte breit ist, also in CSS-Code gesprochen: grid-column: auto / span 1;.

Fertiges Layout, flexible in der Höhe, je nach Inhalt gleich hohe Spalten

Die Postionen im Grid sind in den aktuellen Firefox Dev-Tools schön visualisiert. Die Endposition ist manchmal nicht so klar, manchmal hilft es, wenn man die Hand zur Hilfe nimmt, die Grid-Spalten sind immer die Zwischenräume zwischen den Finger. So beginnt das Grid dann immer mit dem ersten Finger (Pos. 1) und endet mit der letzten Position, bei einem 3-spaltigen Grid ist das die Position 4.

Für unser Layout brauchen wir im Grunde nur 5 Zeilen CSS:

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 12px;
}

.a {
  grid-column: auto / span 2;
}

.b {
  grid-row: auto / span 2;
}

Codepen-Beispiel (für Browser die Grids unterstützen ohne Fallback):

See the Pen CSS Grid by example, simple 3 column grid component layout by Sven Wolfermann (@maddesigns) on CodePen.

Definierte Gridlinien-Benennung

Zudem gibt es die Möglichkeit Gridlinien-Benennung in der Gridvorlage zu vergeben. Dies passiert im grid-template-*, Liniennamen werden umschlossen mit einer eckigen Klammer deklariert. Unser Beispiel mit benannten Gridlinien:

.wrapper {
  display: grid;
  grid-template-columns: [grid-line1] 1fr [grid-line2] 1fr [grid-line3] 1fr [grid-line4];
}
.a {
  grid-column: grid-line1 / grid-line3;
}

Bei der Benennung kann man natürlich kreativer sein. Mit den Liniennamen können dann auch Positionen im Grid vergeben werden.

Der Vollständigkeit halber hier der Code für die Zellen .c und .d, wenn man die Positionen fixieren möchte. Da sich Gridzellen grundsätzlich im autoflow verteilen, wäre der Code aber für das erwartete Ergebnis unnötig.

.a {
  grid-column: 1 / span 2;
}
.b {
  grid-column: 3;
  grid-row: 1 / span 2;
}
.c {
  grid-column: 1;
  grid-row: 2;
}
.d {
  grid-column: 2;
  grid-row: 2;
}

An dieser Stelle auch der Hinweis, dass sich durch Grid super einfach die visuelle Reihenfolge der Elemente mit CSS manipulieren lässt. Bei Flexbox ist dies mit order möglich. Bei Grids greift hier die Positionierungslogik, so kann man ganz simpel eine Navigation vom „Header“ in den „Footer“ verschieben, wenn man das möchte. Die Source-Order im HTML bleibt davon unberührt. Hier muss man prüfen, ob das nicht die Barrierefreiheit beeinträchtigt, wenn man es anwendet.

Browser Support

Der Browser-Support bei neuen CSS-Eigenschaften ist immer etwas spezielles, teilweise muss man Jahre warten bis alle Browser die Eigenschaften unterstützen, damit man den Code produktiv einsetzen kann. Bei CSS Grids gibt es eine Besonderheit, alle modernen Browser unterstützen nahezu zeitgleich die Eigenschaft und wer den Internet Explorer oder MS Edge unterstützt, hat Glück, da bereits der IE10 CSS Grids der ersten Spezifikation unterstützt. Microsoft hat die Eigenschaften entwickelt und in den IE10 integriert. Seither haben die anderen Browserhersteller zusammen mit Microsoft an einem W3C-Standard gearbeitet und die überarbeitete Fassung in die Browser implementiert. So ist es mit Autoprefixer möglich einige Eigenschaften automatisch für die alten Internet Explorer zu generieren, allerdings nur für die Eigenschaften, die der IE unterstützt. Eine gute Übersicht hat Rachel Andrew zusammengestellt. Zu Bedenken ist aber, dass alte Android-Versionen CSS Grids nicht unterstützen. Zudem ist zu empfehlen, dass der Browser-Support mit @support im CSS zu überprüfen ist und die Grid-Eigenschaften in die At-Rule gekapselt werden. Polyfills gibt es in der Form nicht, da es eine vollkommen neue Layout-Technik ist, die zudem die ganze Seite betreffen kann, was, wenn man mit Javascript das Layout beeinflusst, sehr performance-intensiv sein kann.

Aktuell unterstützen Firefox 52, Chrome 57 und Safari 10.1 sowie iOS 10.3, Android Chrome sowie Android Firefox die aktuelle Spec. Internet Explorer ab Version 10 (auch mobile) und Microsoft Edge unterstützen grundlegenden Grid-Eigenschaften mit Vendor-Präfix. Damit Microsoft auf die aktuelle Spec updated, müssen noch mehr Entwickler das Backlog-Ticket hoch voten.

http://caniuse.com/#feat=css-grid

Fazit:

Die neuen Möglichkeiten von CSS Grid Layout sind fantastisch. Endlich ist es möglich sehr viel einfacher eigene Grid-Layouts ohne spezielle Frameworks umzusetzen. Entwickler und Designer werden in Zukunft viel Freude mit den neuen Eigenschaften haben und endlich komplexe Layout-Anforderungen umsetzen können, die bislang nicht, bzw. sehr schwer möglich waren. Ich empfehle jedem Webentwickler mit Grids zu spielen und die Möglichkeiten auszuloten. Auch wenn man Grids aktuell noch nicht in vielen Projekten produktiv einsetzen kann, so ist zumindest der Internet Explorer diesmal nicht der Spielverderber. Dennoch denke ich, das spätestens in einem Jahr mehr und mehr Projekte mit CSS Grid Layouts umgesetzt werden.

Ich möchte zudem nochmals deutlich machen, dass CSS Grids kein Ersatz für irgendeine bisherige Layout-Technik ist, sondern eine tolle neue Ergänzung zu Flexbox, Float & Co darstellt. Ich bin gespannt welche schönen Ideen Designer haben, jetzt wo sie wissen, dass in modernen Browsern nun technisch viel mehr möglich ist.

Wer noch mehr Beispiele sehen möchte, wie man vom Bootstrap-Grid zum eigenen Grid gelangt, findet in meiner Präsentation „Grids & Glory“ weitere Beispiele. Zudem hab ich auf Codepen eine CSS Grid Collection meiner Tests zusammen gestellt.

4 thoughts on “Native CSS Grid Layouts ohne Framework – ein einfaches Beispiel”

  1. Schön erklärt :-)
    Kleiner Hinweis dazu: „An dieser Stelle auch der Hinweis, dass sich durch Grid super einfach die visuelle Reihenfolge der Elemente mit CSS manipulieren lässt. Bei Flexbox ist dies mit order möglich. Bei Grids greift hier die Positionierungslogik“
    Auch bei Grids kann man die Eigenschaft order zur Veränderung der Reihenfolge der Griditems nutzen. Ist für einfache Fälle sehr praktisch.

Kommentare sind geschlossen.