CSS Grid: Layout mit intelligenter Funktion

Erstellt man eine Website, fließt ein großer Teil der Arbeit in die Platzierung der einzelnen Elemente. Das Layout soll interessant aussehen, gleichzeitig aber auch intuitiv verständlich und übersichtlich sein. Cascading Style Sheets (CSS) liefern das Werkzeug, um Websites ansprechend zu gestalten. Während man mit HTML die Inhalte rudimentär auszeichnet, verwenden Webdesigner CSS für komplexe Gestaltungen. Die Webtechnik wird beständig weiterentwickelt. Mit CSS3 sind neue Techniken hinzugekommen, die die Auszeichnungssprache auch für mobiles Internet und responsives Design nutzbar machen.

Wofür braucht man das CSS-Grid-Layout?

Das mobile Internet stellt Webdesigner vor eine große Herausforderung: Denn diese können aufgrund der Vielzahl unterschiedlich gestalteter Mobilgeräte nicht wissen, welches Format das Display hat, auf dem die Website angezeigt werden soll. Aus diesem Grund ist es wichtig, dass die einzelnen Objekte (Textboxen, Grafiken, interaktive Elemente) selbstständig und gleichzeitig übersichtlich verteilt werden – und zwar unter besonderer Berücksichtigung der jeweiligen Platzverhältnisse, die durch das Display vorgegeben sind.

Früher musste man sich mit den sogenannten Floats behelfen. Doch die Arbeit mit dieser Technik war komplex und anfällig für Fehler. Inzwischen gibt es gleich zwei Methoden, ein dynamisches Layout zu realisieren: Neben CSS Grid kann man beispielsweise auch sehr gut Flexbox zur Umsetzung eines smarten Designs nutzen. Doch die beiden Techniken unterscheiden sich in einigen Aspekten.

Flexbox ist eindimensional. Die Elemente werden im Prinzip nur auf einer Achse verschoben. Ein CSS Grid Layout bietet dem Webdesigner zwei Dimensionen zur Platzierung der Objekte. Statt nur auf einer Achse kann man mit CSS Grid ein Raster mit Zeilen und Spalten verwenden.

CSS Grid: Tutorial mit Beispielen

Wer bereits Erfahrungen mit CSS gemacht hat, wird mit Grid keine Probleme haben. Im folgenden Tutorial sind die wichtigsten Funktionen für den Einstieg beschrieben.

Hinweis

Das Tutorial arbeitet mit einer einzigen Datei: Der CSS-Code wird direkt in den Kopf der HTML-Datei geschrieben. Es ist aber selbstverständlich auch möglich, ein separates Stylesheet zu erstellen und dieses nur in der HTML-Datei aufzurufen.

Erstellen von Containern und Items

CSS Grid kennt zwei verschiedene Einheiten: Container und Items. Der Container ist die oberste Ebene. Dort legt man Eigenschaften fest, die dann an alle Items weitergegeben werden. Ein Item liegt also (hierarchisch gesehen) innerhalb eines Containers. Daneben braucht man aber nach wie vor auch HTML für das Grid Layout. Im HTML-Teil des Quelltextes werden die einzelnen Objekte (Text, Grafik, …) erzeugt, die dann innerhalb von CSS Grid aufgegriffen und in die richtige Position gebracht werden.

<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
  display: grid;
}


</style>
</head>
<body>

<div class="grid-container">
  <div class="grid-item1">1</div>
  <div class="grid-item2">2</div>
  <div class="grid-item3">3</div>
  <div class="grid-item4">4</div>
  <div class="grid-item5">5</div>
  <div class="grid-item6">6</div>
</div>

</body>
</html>

Damit haben wir nun sechs Elemente erzeugt, diese jeweils als „grid-item“ definiert und alle in den „grid-container“ gepackt. Damit CSS Grid überhaupt aktiv wird, muss man im Container mit „display: grid“ die Funktion starten. Bisher erzeugt der Code allerdings nur 6 Zahlen, die untereinander erscheinen. Wurden sie erstmal erzeugt, kann man diese Items dann aber relativ frei auf dem Bildschirm platzieren.

Grid, Columns und Rows

Bei CSS Grid arbeitet man mit Zeilen und Spalten und erzeugt auf diese Weise ein Raster. Innerhalb des Rasters lassen sich die einzelnen Objekte anordnen. Dieses Grid kann bzw. muss frei gewählt werden: Der Nutzer selbst entscheidet, welchen Umfang die Zeilen und Spalten haben. Dafür fügt man dem Container zwei Anweisungen zu.

.grid-container {
	display: grid;
	grid-template-rows: 100px 100px;
	grid-template-columns: 100px 100px 100px;
}

Mit diesen beiden Befehlen haben wir ein 2-x-3-Raster aufgemacht. Wie man erkennen kann, lässt sich die Größe jeder Zeile und jeder Spalte einzeln einstellen. Die Angaben werden einfach nacheinander (mit einem Leerzeichen voneinander getrennt) eingetragen. Neben der genauen Pixelangabe kann man auch einen prozentualen Anteil oder andere in CSS übliche Größenordnungen verwenden. Mit den Angaben „max-content“ und „min-content“ kann man das Raster auch in Relation zum Inhalt erstellen lassen.

Mit der Anweisung „grid-gap“ erzeugt man zudem einen Zwischenraum.

.grid-container {
	display: grid;
	grid-template-rows: 100px 100px;
	grid-template-columns: 100px 100px 100px;
	grid-gap: 5px;
}

Damit sind die Zellen gleichmäßig voneinander getrennt. Wer keine einheitlichen Abstände möchte, der kann mit „grid-column-gap“ und „grid-row-gap“ die Zwischenräume auch individueller gestalten.

Eine Besonderheit stellen Fractions dar. Mit dieser Maßeinheit lässt sich der Bildschirm – ähnlich wie mit Prozentangaben – individuell einteilen. Sagen wir, wir möchten den Bereich in 7 horizontale Einheiten aufteilen. Eine einzelne Spalte soll aber doppelt so groß wie die anderen sein. Das lässt sich über folgenden Code umsetzen:

.grid-container {
	display: grid;
	grid-template-rows: 100px 100px;
	grid-template-columns: 1fr 2fr 1fr 1fr 1fr;
	grid-gap: 5px;
}

Der Vorteil, wenn man statt mit statischen Angaben mit relativen Größen arbeitet, ist folgender: Das Raster kann sich automatisch an die Bildschirmgröße anpassen. Auch wenn die einzelnen Spalten kleiner werden müssen, bleibt (in unserem Beispiel) die zweite Spalte immer doppelt so groß wie die anderen. Möchte man eine Zeile fixieren, also nicht an die Bildschirmgröße anpassen, gibt man dieser Reihe einfach einen statischen Wert.

Platzierung von Elementen

Nachdem man das Raster definiert hat, kann man die verschiedenen Objekte platzieren. Dafür muss man Items anlegen und darüber hinaus Start- und Endwerte angeben. Doch muss nicht jedes Element zwingend nur eine Zelle innerhalb des Gitternetzes einnehmen.

<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
  display: grid;
  grid-template-rows: 100px 100px 100px 100px;
  grid-template-columns: 100px 100px 100px 100px;
  grid-gap: 5px;
}

.grid-item1 {
  background: blue;
  text-align: center;
  border: black 5px solid;
  grid-column-start: 1; 
  grid-column-end: 5; 
  grid-row-start: 1; 
  grid-row-end: 3;
}

.grid-item2 {
  background: grey;
  text-align: center;
  border: black 5px solid;
}

</style>
</head>
<body>

<div class="grid-container">
  <div class="grid-item1">1</div>
  <div class="grid-item2">2</div>
  <div class="grid-item2">3</div>
  <div class="grid-item2">4</div>
  <div class="grid-item2">5</div>
  <div class="grid-item2">6</div>
</div>

</body>
</html>

Wir haben nun zwei Item-Typen eingeführt. Während die letzten fünf Elemente automatisch nur die Spannweite einer Zelle haben, reicht das erste Objekt über vier Spalten und zwei Zeilen. (Zur besseren Anschaulichkeit enthalten unsere Beispiele auch weitere visuelle Gestaltung. Farbgebung, Rahmen und Textzentrierung legt man allerdings eigentlich nicht über CSS Grid fest.)

Die Werte für Anfang und Ende der Objekte beziehen sich nur indirekt auf Reihen und Spalten. Tatsächlich referiert man auf die jeweilige Gitterlinie. Im Beispiel endet die vierte Spalte mit der fünften Linie. Man hat aber verschiedene Möglichkeiten, die Spannweiten anzugeben.

  • Nummerierung: Man zählt die Linien von links nach rechts und von oben nach unten.
  • Namen: Innerhalb von „grid-template-rows“ und „grid-template-columns“ kann man den Linien Namen geben (in eckigen Klammern) und dann auf diese Bezeichnungen referieren.
  • Spanne: Mit „span“ gibt man an, wie viele Zellen das Objekt in der entsprechenden Richtung umfassen soll.

Statt Start- und Endpunkt jeweils in einer einzelnen Anweisung zu definieren, können Webdesigner beides auch unter einem Kommando zusammenfassen. Der folgende Code führt zum gleichen Ergebnis wie das vorangegangene Beispiel.

<style>
.grid-container {
  display: grid;
  grid-template-rows: 100px [Line1] 100px [Line2] 100px [Line3] 100px [Line4];
  grid-template-columns: 100px 100px 100px 100px;
  grid-gap: 5px;
}

.grid-item1 {
  background: blue;
  text-align: center;
  border: black 5px solid;
  grid-column: 1 / span 4;
  grid-row: 1 / Line2; 
}

.grid-item2 {
  background: grey;
  text-align: center;
  border: black 5px solid;
}

</style>

Zuweisung von Gebieten

In CSS Grid ist es möglich, Zellen zu Areas zusammenzufassen und diese auch zu benennen. Dies macht dann die Aufteilung der einzelnen Elemente innerhalb des Rasters um einiges einfacher. Die Einstellung dafür nimmt man im Container vor. Dafür verwendet man die Anweisung „grid-template-areas“ und schreibt dann Zeile für Zeile die gewünschten Bereichsnamen in die Zellen. Möchte man eine Zelle nicht zuordnen und damit auch langfristig leer lassen, fügt man an diese Stelle einen Punkt ein. Jede Zeile wird mit Anführungszeichen eingeklammert.

.grid-container {
	display: grid;
	grid-template-rows: 100px 100px 100px;
	grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
	grid-gap: 5px;
	grid-template-areas:
	"area1 area1 area1 area1 area1"
	"area2 area2 . area3 area3"
	"area2 area2 area4 area4 area4";
}

In diesem CSS-Grid-Beispiel haben wir 4 verschiedene Bereiche festgelegt. Eine Zelle ist frei geblieben. Wenn man nun die Items definiert, braucht man keine Von-bis-Werte mehr angeben. Es genügt, auf das zugehörige Areal zu verweisen.

.grid-item1 {
	background: blue;
	text-align: center;
	border: black 5px solid;
	grid-area: area1;
}
.grid-item2 {
	background: red;
	text-align: center;
	border: black 5px solid;
	grid-area: area2;
}
.grid-item3 {
	background: green;
	text-align: center;
	border: black 5px solid;
	grid-area: area3;
}
.grid-item4 {
	background: yellow;
	text-align: center;
	border: black 5px solid;
	grid-area: area4;
}

Ausrichtung anpassen

Wie richten sich die einzelnen Elemente innerhalb von CSS Grid aus? Der Standard ist, dass die einzelnen Elemente so ausgedehnt werden, dass sie genau in das Raster passen. Die Item-Größe spielt daher keine Rolle und wurde deshalb in den Beispielen bisher auch nicht angegeben: Stattdessen haben wir angegeben, über welche Zellen sich das Objekt verteilen soll. Nun kann es aber sein, dass man dem Item eine feste Größe zuweist, und es trotzdem in das Raster integrieren möchte.

Webdesigner haben die Wahl, die Ausrichtung aller Items global über den Container festzulegen oder aber ausgewählten Objekten eine individuelle Ausrichtung zu geben. Für die globale Variante verwendet man „justify-items“ und „align-items“. Ersteres regelt die horizontale Ausrichtung, letzteres die vertikale. Möchte man nur ein einzelnes Item ausrichten, verwendet man die Anweisungen „justify-self“ und „align-self“. Alle Befehle beinhalten allerdings dieselben Optionen.

  • stretch: Die Größe des Objekts wird an die Größe der ausgewählten Zellen angepasst.
  • start: Das Objekt richtet sich nach links bzw. oben aus.
  • end: Das Objekt richtet sich nach rechts bzw. unten aus.
  • center: Das Objekt richtet sich mittig aus.
.grid-container {
	display: grid;
	grid-template-rows: 100px 100px 100px 100px;
	grid-template-columns: 100px 100px 100px 100px;
	grid-gap: 5px;
	justify-items: center;
	align-items: center;
}
.grid-item1 {
	background: grey;
	text-align: center;
	border: black 5px solid;
	width: 50px;
	height: 50px;
}
.grid-item2 {
	background: blue;
	text-align: center;
	border: black 5px solid;
	width: 50px;
	height: 50px;
	justify-self: start;
	align-self: start;
}

Man kann die Anweisungen auch abkürzen, indem man „place-items“ oder „place-self“ verwendet. Es lassen sich beide Informationen (vertikal und horizontal) in nur einer Zeile unterbringen: place-items: <align-items> / justify-items>.

place-items: center / end;

Es ist also möglich, Objekte im Raster auszurichten. Man kann allerdings auch das komplette Raster innerhalb des Containers verschieben. Arbeitet man mit statischen Größenangaben für das CSS Grid, hat das Raster mitunter nicht die gleiche Größe, wie der komplette Container. Dann kann man mit „justify-content“ und „align-content“ auch das Raster innerhalb des Containers – und damit auch innerhalb des Displays – ausrichten. Auch hierbei gibt es verschiedene Möglichkeiten zur Ausrichtung:

  • start: linksbündig oder nach oben ausgerichtet
  • end: rechtsbündig oder nach unten ausgerichtet
  • center: mittig ausgerichtet
  • stretch: ausgedehntes Raster
  • space-around: gleichmäßige Verteilung von Platz um die Zellen herum
  • space-between: gleichmäßige Verteilung von Platz zwischen den Zellen
  • space-evenly: gleichmäßige Verteilung von Platz um die Zellen herum inklusive dem Rand
.grid-container {
	display: grid;
	width: 800px;
	height: 800px;
	background: yellow;
	grid-template-rows: 100px 100px 100px 100px;
	grid-template-columns: 100px 100px 100px 100px;
	grid-gap: 5px;
	justify-content: space-evenly;
	align-content: center;
}

Auch für diesen Fall gibt es eine Kurzversion: place-content: <align-content> / <justify-content>.

place-content: center / space-evenly;

Automatische Anpassungen für responsive Designs

Ein wesentlicher Vorteil von CSS Grid ist die Flexibilität des Rasters. Man kann CSS Grid so einstellen, dass es sich automatisch anpasst. Das macht nicht nur die Darstellung auf verschiedenen Geräten besser: Automatismen helfen auch dabei, die Arbeit mit CSS zu erleichtern.

Eine hilfreiche Funktion nennt sich „repeat()“. Statt jede Zeile oder Spalte einzeln zu definieren, kann man alternativ auch nur eine Größenangabe machen und festlegen, wie häufig dieses Schema wiederholt werden soll. Noch einfacher geht das in Kombinationen mit den Optionen „auto-fill“ und „auto-fit“. Dabei überlässt man CSS Grid die Erstellung von Zeilen und Spalten. Mit der ersten Option fügt CSS Grid so viele Zellen wie möglich ein, ohne die Grenze des Containers zu sprengen. Dabei kann es aber passieren, dass Platz ungenutzt übrigbleibt. Die Option „auto-fit“ hingegen passt die einzelnen Zellen so in ihrem Umfang an, dass der Platz bis an den Rand ausgenutzt wird.

.grid-container {
	display: grid;
	width: 800px;
	height: 800px;
	grid-template-rows: repeat(auto-fit, 100px);
	grid-template-columns: repeat(auto-fit, 100px);
	grid-gap: 5px;
}

Sehr hilfreich sind auch die beiden Funktionen „grid-auto-columns“ und „grid-auto-rows“. Mit diesen beiden Anweisungen hat man mehr Freiheiten beim Erstellen der Items. Hätte beispielsweise ein Raster die Ausmaße von 4 x 4 Zellen und man würde nun ein Item erzeugen, das erst in der fünften Spalte beginnen soll, würde das zu Problemen führen. Durch die automatische Erstellung von genügend Zeilen und Spalten kann man solche Probleme verhindern.

.grid-container {
	display: grid;
	grid-auto-rows: 100px;
	grid-auto-columns: 100px;
	grid-gap: 5px;
}

Auch wenn die Größe von Raster und Objekten sich an die Größe des Displays anpassen sollen, möchten Webdesigner gern Minimal- und Maximalwerte eingeben. Mit der Anweisung „minmax()“ kann man sichergehen, dass ein Item nicht zu klein oder zu groß wird. In die Klammern trägt man dafür zunächst den kleinsten Wert und dann den größten ein.

.grid-container {
	display: grid;
	grid-template-rows: 100px 100px 100px;
	grid-auto-columns: minmax(50px, 150px);
	grid-gap: 5px;
}

Wenn man nun mehrere der vorgestellten Funktionen miteinander kombiniert, kann man sehr leicht ein responsives Design erzeugen.

<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  grid-gap: 5px;
  justify-items: center;
  align-items: center;
}

.grid-item1 {
  background: grey;
  text-align: center;
  border: black 5px solid;
  width: 100px;
  height: 100px;
}


</style>
</head>
<body>

<div class="grid-container">
  <div class="grid-item1">1</div>
  <div class="grid-item1">2</div>
  <div class="grid-item1">3</div>
  <div class="grid-item1">4</div>
  <div class="grid-item1">5</div>
  <div class="grid-item1">6</div>
  <div class="grid-item1">7</div>
  <div class="grid-item1">8</div>
  <div class="grid-item1">9</div>
  <div class="grid-item1">10</div>

</div>

</body>
</html>
Fazit

CSS Grid gibt Webdesignern die Möglichkeit, mit wenig Aufwand ansprechende Layouts zu erstellen. Dank des Rasters hat man dabei immer die Kontrolle über die Platzierung von Objekten – selbst bei einem Responsive Design.