Marc Haunschild: Mein erstes Grid-Layout

CSS Grid gilt nicht umsonst als kompliziert. Das liegt nicht an einer schwer verständlichen Syntax, sondern daran, dass das Grid-Modul sehr umfangreich ist.

Wie bei anderen CSS-Techniken ist es für die ersten Schritte allerdings nicht nötig, alles zu wissen, was mit CSS Grid möglich ist. Das Meistern der Technik kommt dann mit der Übung.

In diesem Blogbeitrag möchte ich Dich bei Deinen ersten Versuchen mit CSS Grid begleiten.

Vorbereitung

Zuerst brauchst du das HTML-Grundgerüst, wie es im Wiki auf der Seite HTML-Grundgerüst  erklärt wird.

In den body kannst du dann Deine Seitenbereiche schreiben, zum Beispiel:

<header></header>

<nav></nav>

<main></main>

<aside></aside>

<footer></footer>

Jetzt möchtest Du sicher, dass der header oben steht, darunter willst du drei Spalten und zuletzt einen footer.

Ein CSS-Raster (Grid) erstellen

Gunnar Bittersmann zeigt in einem Codepen eine Methode, die ich für Anfänger sehr gut geeignet halte, denn sie funktioniert so ähnlich wie skizzieren/malen und ist daher sehr intuitiv.

Grundlage dafür ist es, ein CSS Grid zu erzeugen. Das bedeutet, du erstellst ein Raster, auf dem du deine Elemente anordnen kannst.

Dazu du gibst dem Eltern-Element von allem, was du anordnen möchtest, die Display-Eigenschaft grid:

body {
  display: grid;
}

Dadurch werden alle Kinder von body automatisch zu sogenannten grid-items. Damit kannst du nun eine ganze Menge anstellen.

Schachbrett aus hellem und dunklem Holz statt schwarzer und weißer Felder.
Raster auf einem Schachbrett bestehend aus 8 Spalten und 8 Reihen (Quelle: wikimedia commons)

Aber eins nach dem anderen. Grid bedeutet auf deutsch erst einmal nichts anderes als Raster. Ein Raster findest du beispielsweise auf einem Schachbrett. Es besteht aus Reihen (beim Schach mit Zahlen gekennzeichnet) und aus Spalten (beim Schach mit Buchstaben gekennzeichnet).

Aber wie viele Spalten und Zeilen soll unser Grid haben? Das müssen wir dem Browser mitteilen.

Beginnen wir mit drei Spalten (links, mitte, rechts). Das lässt sich so anlegen:

body {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

Damit legst du drei gleich breite Spalten an, denn 1fr steht für ein Teil (fraction), das den vorhandenen Platz einnehmen darf.

Wenn du drei davon angibst, werden alle gleich breit, denn der verfügbare Platz wird an alle drei Elemente gleichmäßig verteilt, also im Verhältnis 1:1:1.

Du möchtest sicher, dass die mittlere Spalte mehr Platz bekommt, als die beiden anderen. Dafür gibt es zwei Möglichkeiten:

Entweder du gibst der mittleren Spalte mehr Platz, zum Beispiel 2fr oder sogar 3fr. Damit wird die mittlere Spalte doppelt oder gar drei mal so breit, wie die Spalten links und rechts.
Das sieht so aus:

body {
  /* Mitte bekommt 2mal so viel Platz wie die Ränder */
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
}

Oder Du legst mehr als drei Raster-Spalten an und kannst dann dem mittleren Bereich sagen, er soll sich über mehrere Raster-Spalten strecken. Da das ein klein wenig komplizierter ist, werde ich es hier vormachen.

body {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}

Nun haben wir acht Spalten, wie auf einem Schachbrett (das kann man auch kürzer schreiben, aber belassen wir es an dieser Stelle mal dabei…).

Auf diesen Spalten kannst du nun Deine Elemente anordnen. Am einfachsten geht das wie in Gunnars Beispiel, indem du deinen grid-areas Namen gibst:

header {
grid-area: header;
}

nav {
grid-area: nav;
}

main {
grid-area: main;
}

aside {
grid-area: infoBox;
}

footer {
grid-area: footer;
}

Die richtigen Elemente auswählen

Das Problem dabei ist, dass sich einige dieser Elemente mehrfach in Deinem Dokument befinden können (so kann jedes article-Element einen header und einen footer besitzen). Daher müssen wir etwas genauer beschreiben, welchen footer usw wir genau meinen.

Wir wollen genau die Elemente formatieren, die Kinder von body sind. Dafür gibt es den sogenannten Kind-Selektor.

Dabei gibt man das Eltern-Element und das Kind-Element gemeinsam an und kombiniert diese mit dem größer-als-Zeichen:

boddy > header {
  grid-area: header;
}

body > nav {
  grid-area: nav;
}

body > main {
  grid-area: main;
}

body > aside {
  grid-area: infoBox;
}

body > footer {
  grid-area: footer;
}

Von jetzt an ist klar, dass alle Formatierungen, die du an diesen Elementen vornehmen wirst, auch nur genau diese Elemente betreffen werden.

Ausgewählte Elemente auf dem Raster platzieren

Du hast jetzt also so etwas:

Spalte1 Spalte2 Spalte3 Spalte4 Spalte5 Spalte6 Spalte7 Spalte8

Ohne das extra angegeben zu haben, darfst du aber deine Elemente zusätzlich auf beliebig vielen Zeilen angeben. Also so:

Spalte1 Spalte2 Spalte3 Spalte4 Spalte5 Spalte6 Spalte7 Spalte8
Spalte1 Spalte2 Spalte3 Spalte4 Spalte5 Spalte6 Spalte7 Spalte8
Spalte1 Spalte2 Spalte3 Spalte4 Spalte5 Spalte6 Spalte7 Spalte8

Wäre es nicht toll, wenn man das genauso im CSS angeben könnte? Das geht!

Um Deine Elemente jetzt auf diese Spalten zu verteilen schreibst du das genauso in dein CSS, nur mit den Namen, die du vergeben hast. Dazu benötigst du die Eigenschaft grid-template-areas.

Dahinter gibst du dann die Spalten so wie oben an (Achte nur darauf, dass jede Zeile in Anführungszeichen gehört und die Deklaration wie immer in CSS mit einem Semikolon abgeschlossen wird):

body {
  grid-template-areas:
    "header header header header header header header  header"
    "nav   nav   main   main   main   main   infoBox infoBox"
    "footer footer footer footer footer footer footer  footer";
}

Das Raster ist damit fertig. Füge nun noch Farben hinzu, damit du die einzelnen Boxen voneinander unterscheiden kannst:

body > header {
  grid-area: header;
  background-color: gray;
}

body > nav {
  grid-area: nav;
  background-color: lightcyan;
}

  body > main {
  grid-area: main;
  background-color: lightyellow;
}

body > aside {
  grid-area: infoBox;
  background-color: lightcyan;
}

body > footer {
  grid-area: footer;
  background-color: gray;
}

Mobile first!

Bleibt eigentlich nur noch das Problem mit den kleinen Bildschirmen. Bisher ging es nur darum, wie man Boxen auf einem Grid/Raster platziert. Daher habe ich das gezeigt. Damit anzufangen wird aber aus vielen Gründen nicht empfohlen.

Man kümmert sich zuerst nur um die Darstellung auf den kleinsten Geräten, also Smartphones oder gar Smartwatches.

Da machen mehrere Spalten keinen Sinn. Ich möchte also, dass die Spalten nur erscheinen, wenn der Bildschirm groß genug ist, um drei Spalten nebeneinander darzustellen. Dafür gibt es media-queries.

Auch hierfür gibt es wieder mehrere Ansätze. Gunnar hat im oben verlinkten CodePen den eleganteren gewählt (das gesamte Grid wird nur erzeugt, wenn auch genug Platz für mehrere Spalten vorhanden ist).

Ich wähle hier einen anderen, weil er zeigt, wie man für verschiedene Bildschirmauflösungen mit der hier erklärten Methode unterschiedliche Layouts erstellen kann.

Es geht also nur darum, dass auf Smartphones alle Spalten des Rasters nur einem Element zur Verfügung gestellt werden. Also so etwas:

body {
  grid-template-areas:
    "header  header  header  header  header  header  header  header"
    "nav     nav     nav     nav     nav     nav     nav     nav"
    "main    main    main    main    main    main    main    main"
    "infoBox infoBox infoBox infoBox infoBox infoBox infoBox infoBox"
    "footer  footer  footer  footer  footer  footer  footer  footer";
}

Das sieht erst mal nach viel Schreiberei aus, aber dank Copy & Paste ist das schnell erledigt.

Die Angaben für die einspaltige Darstellungen gehören zuerst in das CSS.

Das was wir vorher hatten, setzen wir in folgendes Konstrukt:

@media screen and (min-width: 40em) {
/* CSS Regeln, die hier stehen, werden nur angewendet,
wenn der Platz im Browser (Viewport) mindestens so breit ist
wie 40 mal der Buchstabe 'm' */
}

Wie das aussieht, wenn du alles zusammen packst, siehst in meinem Codepen CSS-Grid mit benannten grid-areas.

Natürlich kannst du mit dieser Methode weitere Layouts bereitstellen. Kopiere einfach die @media-Regel und platziere Deine grid-areas je nachdem wie es für die jeweilige Viewport-Größe sinnvoll ist. Auch vier oder fünf verschiedene Layouts sind so in wenigen Minuten umgesetzt.

Weitere Artikel zum Thema CSS Grid mögen folgen. Wenn du aber jetzt schon neugierig bist auf mehr, lies dich doch im Wiki weiter ins Thema ein. Auch dort findest du weitere Beispiele.

Have fun!

  1. Das war bis jetzt die anschaulichste und anfängerfreundlichste Einführung in das Thema, die ich gesehen habe. Tausend Dank dafür!
  2. Das 8-Spalten-Grid halte ich für keine so gute Idee. Begründung im Forum.
  3. Das sieht erst mal nach viel Schreiberei aus, aber dank Copy & Paste ist das schnell erledigt.
    Wenn man Copy & Paste als Werkzeug beim Programmieren/Entwickeln einsetzt, macht man wahrscheinlich etwas falsch.
  4. Hallo Gunnar, Danke für die Anmerkungen. Copy & Paste halte ich für eine extrem wichtige Methode bei der Entwicklung. Besonders deutlich wird das an dem hier gezeigten Beispiel. Hier acht mal dasselbe händisch einzutippen (multipliziert mit der Anzahl der Media-Queries), birgt bei jeder einzelnen Eingabe die Gefahr von Tippfehlern, die gerade für Anfänger schwer zu finden sind. Daher möchte ich im Gegensatz zu dir zum bewussten Kopieren ermutigen, zumal hier gar nichts programmiert wird. Die acht Spalten sind tatsächlich ein „Problem“, weil diese nicht wirklich nötig zu sein scheinen. Ich halte das Bild vom Schachbrett aber für sehr gut nachvollziehbar. Daher habe ich das beibehalten. Wenn man CSS Grid erst mal verstanden hat, wird man schon selber drauf kommen, wie viele Spalten man für sein persönliches Layout tatsächlich benötigt. Wir wissen über die zu erstellenden Layouts ja nichts. Es ist nicht klar, wie die tatsächliche Website mal aussehen wird in den unterschiedlichsten Bildschirmauflösungen. Vielleicht werden die acht Spalten sogar sinnvoll sein - oder zwölf oder drei. Dein sehr knappes, auf die kürzestmögliche Schreibweise reduziertes Beispiel habe ich übrigens als elegante Lösung hier benannt und verlinkt. ;-)
  5. Vielen Dank für die freundliche Rückmeldung. Auch positive Kritik hilft mir für zukünftige Artikel. Und man hört sie auch gerne! ;-)
  6. „CSS Grid gilt nicht umsonst als kompliziert“ halte ich für einen Fehlstart in den Artikel. Zum einen schreckt das Leser eher ab anstatt sie zu ermuntern, zum anderen trifft das überhaupt nicht zu. Grid ist einfachinsbesondere für Neueinsteiger.
  7. Was ich mit „Wenn man Copy & Paste als Werkzeug beim Programmieren/Entwickeln einsetzt, macht man wahrscheinlich etwas falsch“ meinte: man sollte Code i.A. nicht duplizieren, sondern bspw. bei Programmiersprachen in Funktionen/Methoden/Klassen auslagern. Bei CSS: wenn verschiedene Elemente gleiche Stile haben, diese zusammenfassen: nicht `#foo {margin: 1rem} .bar {margin: 1rem}`, sondern `#foo, .bar {margin: 1rem}`. Wartbarer Code: wenn der Abstand auf 1.2rem geändert werden soll, ist die Änderung nur an einer Stelle vorzunehmen. (Das wäre bei `:root {--margin: 1rem} #foo {margin: var(--margin)} .bar {margin: var(--margin)}` auch gegeben.)
    Wenn man CSS Grid erst mal verstanden hat, wird man schon selber drauf kommen, wie viele Spalten man für sein persönliches Layout tatsächlich benötigt.
    Das Vorgehen „Ich zeige euch, wie man’s besser nicht machen soll; ihr werdet schon selbst drauf kommen, wie’s richtig geht“ halte ich bei einem Tutorial für problematisch.
  8. Hallo Marc, vielen Dank für die für mich sehr gut verständliche Anleitung und besonders den Einschub "Mobile first". Michael
  9. Huch habe gar nicht gesehen, dass du noch mal nachgelegt hast. DRY code ist ein spannendes Thema und sicher auch einen Blog-Post wert. > > Wenn man CSS Grid erst mal verstanden hat, wird man schon selber drauf kommen, wie viele Spalten man für sein persönliches Layout tatsächlich benötigt. > Das Vorgehen „Ich zeige euch, wie man’s besser nicht machen soll; ihr werdet schon selbst drauf kommen, wie’s richtig geht“ halte ich bei einem Tutorial für problematisch. Das hast du vielleicht falsch verstanden. Ich zeige, wie man mit CSS Grid Spalten erzeugt. Ob acht passend sind oder nicht, kann ich nicht sagen. Ich kenne die Layouts ja nicht. Im Beispiel entsteht ja keine vollständige Webseite. Es ist ja nicht nur denkbar, sondern sehr wahrscheinlich, dass auf einer echten Website noch mehr als Elemente aus dem Beispiel hier zu platzieren sind. Mir ging es darum, eine Anwendungsmöglichkeit von Grid verständlich zu erklären. Das scheint mir gelungen. Dass man nur zwei Spalten anlegen muss, wenn das eigene Layout nur zwei Spalten vorsieht, halte ich für eine Transferleistung, die man nach der Lektüre dieses Posts tatsächlich hinbekommen sollte. Wenn nicht, habe ich etwas falsch gemacht!