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.
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!