CSS/Tutorials/Grid/Grid-Items

Aus SELFHTML-Wiki
< CSS‎ | Tutorials‎ | Grid
Wechseln zu: Navigation, Suche

Das Grid Layout unterscheidet zwischen dem Elternelement Grid-Container und den darin enthaltenen Rasterelementen (Grid-Items). Wie im letzten Beispiel schon angerissen, können die Grid Items beliebig im Raster platziert und dimensioniert werden:

Die Rasterelemente

Unsere Webseite soll ja eben nicht aus gleichgroßen Blöcken bestehen. Deshalb sollen im nächsten Schritt individuelle Festlegungen für jedes einzelne Rasterelement getroffen werden. Die Rasterelemente können einzelne Zellen oder aber einen Rasterbereich (grid area) über mehrere Felder einnehmen.

Der folgende Abschnitt mag verwirrend erscheinen. Grund ist, dass in einer Zeile CSS zwei verschiedene Schritte durchgeführt werden:

  1. Linien werden als Start unserer Rasterelemente selektiert.
  2. Die Rasterelemente erhalten mit Berechnungen zu anderen Rasterlinien ihre Größe.

Anfangs- und Endlinien festlegen

Grid-1.svg

Mit den Eigenschaften

sowie

können Sie Anfangs- und End-Rasterlinien festlegen, die damit die Größe und Position innerhalb der grid row bestimmen.

Übersichtlicher ist die Verwendung der zusammenfassenden Eigenschaften (shorthand properties) grid-column und grid-row:

Die grid-column-Eigenschaft ist die Zusammenfassung der Eigenschaften grid-column-start und grid-column-end, die durch den Slash getrennt werden.

Mögliche Angaben sind:

  • grid-column: 1 / 6;: Das Rasterelement erstreckt sich von der ersten bis zur 6. Rasterlinie.
  • grid-column: 1 / -1;: Es sind auch negative Werte möglich. Das Rasterelement erstreckt sich von der ersten bis zur letzten Rasterlinie (automatisch erzeugte Rasterlinien zählen dabei allerdings nicht mit).
  • grid-column: 1 / span 5;: Das Rasterelement erstreckt sich von der ersten Rasterlinie über 5 Zellen hinweg.
  • grid-column: span 5;: Das Rasterelement erstreckt sich über 5 Zellen hinweg. Ein fester Anfang ist nicht vorgegeben.


Grundraster mit festgelegtem Rasterbereich für den header ansehen …
body {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}

header {
  grid-column: 1 / 6;
  grid-row:    1 / auto;			
}

nav {
  grid-column: 1 / span 5;
  grid-row:    2;		
}

Ausgangspunkt ist wieder unser 5-spaltiger Raster.

Für den header legen wir mit grid-column fest, dass er in der ersten Spalte beginnen und dann am Ende der 5. Spalte ( also an der 6. Rasterlinie) enden soll. grid-row legt fest, dass er von der ersten horizontalen Rasterlinie beginnen soll. Der Wert auto wird als span mit einem Wert von 1 berechnet, sodass das Element eine Zeile hoch ist.

Die Navigation beginnt in der ersten Spalte und erstreckt sich durch das Schlüsselwort span über 5 Spalten. Die vertikale Positionierung beginnt in der 2. Zeile und ist eine Zeile hoch. Da der Defaultwert für grid-row-end ja auto beträgt, muss er nicht mehr explizit erwähnt werden.

Die anderen vier Rasterelemente werden als schmale Spalten in der dritten Zeile dargestellt.


Empfehlung: Öffnen Sie das Beispiel einmal im Frickl und einmal in einem neuen Tab. Bei einem schmalerem Viewport verteilen sich die 4 verbliebenen Rasterelemente auf den verfügbaren Raum, bei breiteren Viewports bleibt rechts eine Spalte frei.
Verändern Sie die Werte für grid-column und grid-row und beobachten Sie die Veränderungen.


In einem weiteren Schritt werden nun für alle Kindelemente des Rasters eigene Rasterbereiche festgelegt:

Grundraster mit festgelegten Rasterbereichen ansehen …
body{
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}

header {
  grid-column: 1 / 5;
  grid-row:    1 / 2;			
}

nav {
  grid-column: 1 / 2;
  grid-row:    2 / 4;					
}

article {
  grid-column: 2 / 4;
  grid-row:    2 / 4;					
}

aside {
  grid-column: 5 / 6;
}

footer {
  grid-column: 1 / 6;
  grid-row:    4 / 5;					
}

Für jedes Kindelement im Raster wird mit grid-column und grid-row ein Rasterbereich (grid area) festgelegt.

Fünf Dinge fallen auf:

  • Der article endet an der 4. Linie, die aside-Boxen beginnen aber erst bei der 5. Linie. Der dazwischenliegende Platz bleibt (im Unterschied zu einer Umsetzung mit Flexbox) leer.
  • Die aside-Boxen erhalten keine Festlegung der Höhe und nehmen dann den Defaultwert von einer Spanne / der Höhe einer Zelle ein. Die zweite aside-Box wird automatisch in einer neuen Zelle unterhalb der ersten platziert.
  • Die Positionierung erfolgt unabhängig von der Reihenfolge im HTML-Markup. (Allerdings sollte dies aus Zugänglichkeitsgründen nur in Ausnahmefällen erfolgen.)
  • Während die Spalten mit grid-template-columns: repeat(5, 1fr); festgelegt wurden, werden die Zeilen auch ohne Festlegung automatisch gebildet.
    Empfehlung: Entfernen Sie die Wertzuweisung für grid-template-columns und beobachten Sie, was passiert.
  • Alle Rasterelemente haben einen margin von .5em, sonst würden die Elemente aneinanderstoßen. (Dies kann aber auch mit gap erreicht werden.)


Beachten Sie: Viele der oben noch verwendeten Festlegungen sind gar nicht nötig: Wenn ein Element nur eine Spalte breit oder eine Reihe hoch sein soll, kann die Festlegung auch weggelassen werden.
Empfehlung: Nutzen Sie die Möglichkeiten des Grid Layout und verwenden Sie die Möglichkeiten der Positionierung nur sparsam. Der Browser verteilt die Elemente ganz von selbst im verfügbaren Platz!

grid-area

Ein Blick in den Seiteninspektor des Firefox verrät, dass diese expliziten Festlegungen vom Browser in der zusammenfassenden Eigenschaft grid-area notiert werden. Dabei werden die Werte von grid-row-start, grid-column-start, grid-row-end und grid-column-end jeweils mit einem Slash (/) notiert:

Rasterbereiche mit grid-area
header {
  grid-area:  1 / 1 / 2 / 6;			
}

/* übersichtlichere Alternative */

nav {
  grid-area: 2 / 1 / auto / span 1;				
}

Kürzer, aber auch unübersichtlicher. Wenn das Layout steht, könnte man die Eigenschaften so zusammenfassen. Durch die Angabe der Schlüsselworts span für die Breite oder Höhe könnte man wieder Übersichtlichkeit gewinnen.

negative Werte

Wenn Sie Elemente über die gesamte Breite (oder bis zum Ende) des Rasters spannen wollen, müssen Sie nicht die Anzahl der Zellen zählen, bzw. den Wert bei einer Änderung der Anzahl der Spalten ändern. Ein negativer Wert beginnt mit der Zählung von rechts, sodass das Element dann alle Spalten überspannt:

Elemente über die gesamte Breite
body{
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}

header {
  grid-column: 1 / -1;
  grid-row:    1 / 2;			
}

Der header beginnt an der ersten Rasterline. Das Ende befindet sich durch den Wert -1 am Beginn von rechts, also dem Ende des Rasters.

Anwendungsbeispiele

feststehender Footer

Grundraster ansehen …
body {
	display: grid;
	grid-template-columns: 1fr 3fr 1fr;
	grid-template-rows: min-content 1fr 1fr min-content;
	gap: .5em;
	min-height: 100vh;
}
...
footer {
  grid-column: 1 / span 3;
  grid-row:    4;					
}

Der body wird durch display: grid zu einem Grid Container. Die direkten Kindelemente können nun innerhalb eines Rasters angeordnet werden.

Mit grid-template-columns: 1fr 3fr 1fr; werden nun drei Spalten festgelegt, die den verfügbare Breite im Verhältnis der Bruchteile (hier 1 : 3 : 1) untereinander aufteilen.

Mit grid-template-rows: min-content 1fr 1fr min-content; werden nun vier Zeilen festgelegt. Während die obere und untere Zeile sich mit min-content anhand des vorhandenen Inhalts orientieren, teilen die beiden mittleren Zeilen den verfügbaren Raum unter sich im Verhältnis der Bruchteile fr (hier 1:1) unter sich auf.

Die sechs Kindelemente (Grid Items) werden mit grid-column und grid-row passend positioniert; der footer nimmt zum Beispiel den Raum zwischen 4. und 5. horizontaler Rasterlinie (also die 4. Zeile) ein. In grid-column ist festgelegt, dass er an der ersten vertikalen Rasterlinie beginnt und (alle) 3 Spalten überspannt.


Definitionsliste nebeneinander

Die Elemente von Definitions- oder Beschreibungslisten werden in der browsereigenen Darstellung untereinander angezeigt. Das Platzieren der Blöcke kann schwierig werden, da bei mehreren dd-Elementen ein gemeinsames Elternelement fehlt. Mit Grid Layout ist es möglich, Definitionslisten in ein kompaktes Raster zu fassen.

Formular ansehen …
dl {
  display: grid;
  grid-template-columns: auto 1fr;
  max-width: 18em;
  margin: 1em;
  line-height: 1.4;
}
dt {
  grid-column: 1;
  font-weight: bold;
}
dd {
   grid-column: 2;
 }

Die Beschreibungsliste dl besteht aus zwei Spalten, deren erste sich am vorhandenen Inhalt ausrichtet. Die zweite nimmt den verfügbaren restlichen Raum ein.

Der dt-Ausdruck beginnt an der ersten Rasterlinie, also in der 1. Spalte, die Beschreibungen dd immer in der zweiten.


Fazit

Ich habe nun drei Jahre Erfahrung mit dem mittlerweile nicht mehr ganz neuen Grid Layout:

Der stärkste Vorteil des Grid Layout ist seine Flexibilität, mit der die Elemente im Raster verteilt werden. Bei einigen Elementen mit viel Inhalt ist es wichtig und richtig, sie über mehrere Zellen erstrecken zu lassen.

Generell sollte man aber (fast) alles den Browser machen lassen. Genau wie eine pixelgenaue Positionierung wenig sinnvoll ist, so wenig nützen zu viele Angaben zur genauen Position für alle Rasterlemente. Besser als feste Pixelangaben sind reative Angaben in rem oder em, noch besser sind angaben wie min-content oder fit-content.

Im nächsten Kapitel erfahren Sie, wie Sie die Raster (bzw. die Anzahl der Felder pro Reihe) ohne media queries responsiv gestalten können.

--Matthias Scharwies (Diskussion) 06:33, 14. Mär. 2020 (CET)