CSS/Tutorials/Grid/Verschachtelte Raster

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

Das Grid Layout ist perfekt für zweidimensionale Raster in flachen HTML-Strukturen wie Bildergalerien.

Häufig gab es Verständnisprobleme, warum sich Elemente nicht in das Raster einfügten: Ein Blick in das HTML-Markup zeigte, dass sie Teil einer verschachtelten Struktur wie Navigationen oder Inhalte von section-Elementen waren, die eben keine direkten Kindelemente des Grids waren.

Mit dem CSS Grid Layout Module Level 2 ist es nun möglich, verschachtelte Raster (subgrids) zu erzeugen, die sich automatisch an das „Eltern-Raster“ anpassen.[1]

herkömmliche Vorgehensweise

Ein Element wird mit display: grid zu einem Grid-Container, dessen direkte Kinder sich dann als Grid-Items in ein Raster ordnen. Kinder dieser Grid-Items (Kindeskinder des Grid-Containers) werden aber wieder im normalen Elementfluss platziert.

Bisher konnten Raster verschachtelt werden, indem das Grid-Item mit display: grid zu einem weiteren Grid-Container wurde. Dabei störten aber Abstände wie gap, padding und margin, die dann entsprechend angepasst werden mussten.

In diesem Beispiel besteht der article aus einer Produktvorschau mehrerer Karten, die mit einem figure-Element mit 3 Kind-Elementen realisiert werden:

Galerie mit Cards
<article class="main-grid-container">
  <figure class="grid-item">
    <h3 class="card-title"></h3>
    <img src="bild.svg" alt="Erklärung für Screenreader">
    <figcaption class="card-text">
      ...
      <a class="card-link" href="#">Mehr …</a>
    </figcaption>
  </figure>
  <figure class="grid-item">
    ...

Jedes figure-Element wird zu einem eigenen Grid-Container, der den Inhalt auf den jeweils verfügbaren Platz aufteilt. Dabei entstehen aber je nach Textlänge unterschiedlich große Überschriften und figcaptions:

verschachteltes Grid mit 2 unabhängigen Rastern
article {
    display: grid;
    grid-template-columns: repeat[4, 1fr);
}

figure {
    display: grid;
    grid-template-rows: auto 1fr auto;
}

verschachteltes Grid mit unterschiedlichen Höhen


Eine Angleichung dieser Werte war bisher nur mit verpönten Magic Numbers möglich.

subgrid

In Level 2 der CSS Grid Layout Spezifikation können die Werte für grid-template-columns und grid-template-rows mit dem Schlüsselwort subgrid ergänzt werden, mit dem Sie das Raster auch in weiteren Kindeskind-Elementen fortführen können.[2]

Grundraster und Raster für die Cards
.main-grid-container {	/* article */
  display: grid;
}

.grid-item {			/* figure */
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
}


Dabei reicht es, einfach ein neues Grid aufzumachen. Mit dem Schlüsselwort subgrid verwendet das verschachtelte Raster die im übergeordneten Raster definierten tracks, anstatt für jede Karte eine neue track list zu erstellen.

Das wollen wir nun einmal am oberen Beispiel unserer Cards demonstrieren:


verschachteltes Grid mit subgrid ansehen …
.main-grid-container {  /* article */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12em, 16em));
}

.grid-item {				/* figure */
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;	
  row-gap: 0;
}

Während der Grid-Container die Cards in einem Raster passend verteilt, liegen die Detail-Informationen im figure-Element, dem Grid-Item.

Dort werden die grid-template-rows als subgrid angelegt, wobei das Grid-Item mit grid-row: span 3 über drei Rasterfelder gestreckt wird. Da sich der Grid-Container des figure-Elements nach dem Eltern-Grid des article-Elements ausrichtet, haben jetzt alle h3-Überschriften, die Bilder und auch die figcaption jeweils die gleiche Höhe, auch wenn z.B. das linke Bild ein ganz anderes Format hat.

Blogpost im zweidimensionalen Raster

Wussten Sie schon, dass die Schreinerei Meier aus dem HTML-Einstieg einen Blog hat? - Jeder Blogeintrag soll auf der Startseite vorgestellt werden. Dabei sollen anstatt einer Linkliste wieder Cards verwendet werden, die aber ein zweidimensionales Raster enthalten:


HTML-Markup eines Blog-Posts
<body class="main-grid-container">
	<article class="grid-item">
		<h2 class="post-title">...</h2>
		<p class="subtitle">...</p>
		<a href="#" class="author"><img src="logo.svg" alt="Logo für die Schreinerei Meier"></a>
		<img src="Desk.svg" alt="maßgefertigter Schreibtisch">
		<p class="post-text">...</p>
		<meter value="90" min="0" max="100" low="20" high="80" optimum="90">4.5 von 5</meter>
		<a class="post-link" href="#">Mehr …</a>   
  </article>
  <article class="grid-item">
    ...

Während Vorschau-Bild und Text die volle Breite einnehmen, sollen das Autoren-Avatar und der Weiterlesen-Link passend neben anderen Informationen positioniert werden. Deshalb wird die Card zu einem Grid mit 2 Spalten und fünf Reihen, die aber als subgrid-Items im großen Grid des body-Elements stehen:


Blog-Vorschau mit subgrid ansehen …
.main-grid-container {  /* body */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12em, 16em));
}

.grid-item {					/* article */
  display: grid; 
  grid-template-rows: subgrid;
  grid-template-areas:
		"subtitle author" 
		"title    title "
		"image	  image"
		"text	  text"
		"rating   post-link";	
  grid-row: span 5;	
}

.author {
  grid-area: author;
}

Der Aufbau ähnelt dem 1. Beispiel:

  • der body wird zum Raster, das je nach Viewport mit Rasterfeldern aufgefüllt wird, die mit
    grid-template-columns: repeat(auto-fill, minmax(12em, 16em)) zwischen 12 und 16em breit sind.
  • jeder article wird über seine Klasse grid-item zum subgrid.
  • dieses wird von grid-template-areas in einem übersichtlichen Schema definiert.
    Die Höhe der Reihen richtet sich nach dem jeweiligen Inhalt und wird vom Browser berechnet.
    So bleibt die Card auch für unterschiedliche Inhalte flexibel!
  • anschließend wird jedem Rasterelement mit grid-area „seine“ passende Fläche zugewiesen

Das Rating der Artikel mit Sternen wird in Formulare/Ergebnisausgabe näher behandelt.[3]

Fazit

Subgrids sind nützlich, um gleiche Rasterzellen in verschiedenen Geschwister-Elementen zu erzeugen. Sobald Sie so ein verschachteltes Raster in zwei Dimensionen erschaffen haben, können Sie es aber nicht mehr durch die implizierte Erzeugung weiterer Zellen erweitern. Weitere Grid-Items werden im letzten verfügbaren track übereinander dargestellt und verdecken sich so gegenseitig.

Allerdings können Sie nur eine Dimension ihres Subgrids mit subgrid festlegen und damit die andere Dimension so anlegen, dass sich weitere Elemente wie gewohnt einfügen.

Die Browserunterstützung ist heute (Stand: August 2024) mit 90% und allen modernen Browsern als gut zu bezeichnen.
Eine zeitgemäße Alternative wären Container Queries.


Weblinks

  1. W3C: CSS Grid Layout Module Level 2
  2. MDN: Subgrid
    Introduction to subgrid
  3. <meter> star rating (like Amazon) von Sven Wolfermann, nach einer Idee von Lea Verou

Beispiele