Subgrid
Verschachtelte Grids sind normalerweise komplett unabhängig voneinander: Das innere Raster weiß nichts vom äußeren. Genau das macht ausgerichtete Karten-Layouts schwierig, denn jede Karte berechnet ihre Zeilenhöhen selbst. Mit dem Wert subgrid für grid-template-columns und grid-template-rows übernimmt ein verschachteltes Grid die Tracks seines Elterngrids. In diesem Artikel lernst du, wie Subgrid funktioniert, wie du damit Karteninhalte über mehrere Karten hinweg ausrichtest und wie sich gap und benannte Linien im Subgrid verhalten.
- Syntax
- grid-template-columns: subgrid | grid-template-rows: subgrid
- Initialwert
- none
- Vererbt
- Nein
- Animierbar
- Nein
- Kategorie
- Grid
- Werte
- 3
- Beispiele
- 4
- Browser
- 5 von 5
- 0 von 5
- Stand
- 03.07.2026
Grundlagen
Ein Grid wirkt nur auf seine direkten Kinder. Sobald du eine Komponente verschachtelst, zum Beispiel eine Karte mit Titel, Text und Button, erzeugt display: grid auf der Karte ein neues, eigenständiges Raster. Die Zeilen der einen Karte haben keinerlei Beziehung zu den Zeilen der Nachbarkarte. Umbricht ein längerer Titel in einer Karte, verschieben sich Text und Button nur dort. Das Ergebnis kennst du bestimmt: Buttons auf unterschiedlichen Höhen, Textblöcke enden versetzt.
Hier setzt Subgrid an. subgrid ist ein Wert für grid-template-columns und grid-template-rows. Statt eigene Tracks zu definieren, übernimmt das verschachtelte Grid die Tracks des Elterngrids in dieser Achse: Größen, Anzahl und Liniennamen kommen dann vom äußeren Raster. Du kannst subgrid pro Achse unabhängig einsetzen, also nur für Spalten, nur für Zeilen oder für beide gleichzeitig.
Drei Dinge müssen dafür zusammenkommen: Das Element ist ein Grid-Item (direktes Kind eines Grid-Containers), es ist selbst ein Grid-Container (display: grid) und es überspannt die Tracks, die es übernehmen soll (z.B. mit grid-column: 1 / -1 oder grid-row: span 3). Die Anzahl der Tracks im Subgrid ergibt sich immer aus der Spannweite: Überspannt das Item drei Spalten des Elterngrids, hat das Subgrid genau drei Spalten.
Falls die Grid-Grundlagen bei dir noch wackeln, schau dir zuerst Grid Container und Grid Platzierung an. Subgrid baut direkt darauf auf.
Syntax & Werte
3 Wertegrid-template-columns / grid-template-rows
Eigene Track-Größen kannst du mit subgrid nicht kombinieren. Eine Deklaration wie grid-template-columns: subgrid 200px 1fr ist ungültig, denn die Größen kommen immer vom Elterngrid. Erlaubt sind nach dem Schlüsselwort nur Liniennamen in eckigen Klammern.
Beispiele
4 BeispieleDas Elterngrid hat drei unterschiedlich breite Spalten. Das verschachtelte Element spannt sich über alle drei und übernimmt sie mit subgrid. Seine Kinder (A, B, C) sitzen dadurch exakt unter den Items des Elterngrids, inklusive des geerbten Spaltenabstands.
.parent {
display: grid;
grid-template-columns: 100px 1fr 2fr;
gap: 8px;
}
.nested {
grid-column: 1 / -1; /* spannt alle drei Spalten */
display: grid;
grid-template-columns: subgrid; /* übernimmt 100px 1fr 2fr */
}<div class="demo">
<div class="parent">
<div class="p-item">100px</div>
<div class="p-item">1fr</div>
<div class="p-item">2fr</div>
<div class="nested">
<div class="n-item">A</div>
<div class="n-item">B</div>
<div class="n-item">C</div>
</div>
</div>
</div> Der Klassiker: Drei Karten mit Titel, Text und Button. Ohne Subgrid berechnet jede Karte ihre Zeilenhöhen selbst, die Buttons landen auf unterschiedlichen Höhen. Mit Subgrid teilen sich alle Karten dieselben drei Zeilen des Elterngrids. Jede Zeile wird so hoch wie der höchste Inhalt aller Karten, und Titel, Text und Button liegen überall auf derselben Höhe.
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto auto auto;
gap: 8px;
}
.card {
grid-row: span 3; /* Karte belegt drei Zeilen */
display: grid;
grid-template-rows: subgrid; /* Titel, Text und Button
teilen sich diese Zeilen */
}<div class="demo">
<div class="label">Ohne Subgrid: jede Karte rastert selbst</div>
<div class="cards-before">
<div class="card-before">
<div class="card-title">HTML</div>
<div class="card-text">Die Struktur jeder Webseite.</div>
<div class="card-btn">Mehr</div>
</div>
<div class="card-before">
<div class="card-title">CSS Grid und Subgrid</div>
<div class="card-text">Zweidimensionale Layouts, bei denen sich auch verschachtelte Teile am selben Raster ausrichten.</div>
<div class="card-btn">Mehr</div>
</div>
<div class="card-before">
<div class="card-title">JavaScript</div>
<div class="card-text">Logik und Interaktion im Browser.</div>
<div class="card-btn">Mehr</div>
</div>
</div>
<div class="label">Mit Subgrid: Titel, Text und Button auf gemeinsamen Zeilen</div>
<div class="cards-after">
<div class="card-after">
<div class="card-title">HTML</div>
<div class="card-text">Die Struktur jeder Webseite.</div>
<div class="card-btn">Mehr</div>
</div>
<div class="card-after">
<div class="card-title">CSS Grid und Subgrid</div>
<div class="card-text">Zweidimensionale Layouts, bei denen sich auch verschachtelte Teile am selben Raster ausrichten.</div>
<div class="card-btn">Mehr</div>
</div>
<div class="card-after">
<div class="card-title">JavaScript</div>
<div class="card-text">Logik und Interaktion im Browser.</div>
<div class="card-btn">Mehr</div>
</div>
</div>
</div> Ein Subgrid erbt gap, row-gap und column-gap automatisch vom Elterngrid, allerdings nur in der Achse, die auf subgrid steht. In der anderen Achse gilt ganz normal der eigene Abstand des Subgrids. Du kannst die geerbten Werte aber auf dem Subgrid überschreiben. Die äußeren Kanten der Tracks bleiben dabei am Elternraster ausgerichtet, nur die Abstände innerhalb des Subgrids ändern sich.
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
/* Erbt automatisch die 16px des Elterngrids */
.sub-inherit {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
}
/* Überschreibt den geerbten Abstand */
.sub-own {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
column-gap: 4px;
}<div class="demo">
<div class="parent-gap">
<div class="pg-item">Elterngrid</div>
<div class="pg-item">gap:</div>
<div class="pg-item">16px</div>
<div class="sub-inherit">
<div class="sg-item">geerbt</div>
<div class="sg-item">16px</div>
<div class="sg-item">Abstand</div>
</div>
<div class="sub-own">
<div class="sg-item">eigener</div>
<div class="sg-item">4px</div>
<div class="sg-item">Abstand</div>
</div>
</div>
</div> Liniennamen des Elterngrids stehen auch im Subgrid zur Verfügung. Zusätzlich kannst du direkt hinter dem Schlüsselwort subgrid eigene Namen vergeben. Beide Namensquellen funktionieren nebeneinander: Das grüne Item nutzt die geerbten Namen inhalt-start und inhalt-end, das lila Item die eigenen Namen a und c.
.parent {
display: grid;
grid-template-columns: 1fr [inhalt-start] 2fr 2fr [inhalt-end] 1fr;
gap: 8px;
}
.sub {
grid-column: 1 / -1;
display: grid;
/* geerbte Namen bleiben nutzbar,
a bis e kommen zusätzlich dazu */
grid-template-columns: subgrid [a] [b] [c] [d] [e];
}
.mit-eltern-namen { grid-column: inhalt-start / inhalt-end; }
.mit-eigenen-namen { grid-column: a / c; }<div class="demo">
<div class="parent-lines">
<div class="pl-item">1fr</div>
<div class="pl-item">2fr</div>
<div class="pl-item">2fr</div>
<div class="pl-item">1fr</div>
<div class="sub-lines">
<div class="geerbt-item">inhalt-start / inhalt-end (geerbt)</div>
<div class="eigene-item">a / c (eigene Namen)</div>
</div>
</div>
</div> Barrierefreiheit
Subgrid hat einen echten Vorteil für die Barrierefreiheit: Du kannst semantisch sinnvolles, verschachteltes HTML behalten und trotzdem alles am selben Raster ausrichten. Ohne Subgrid wurden Layouts dafür oft künstlich abgeflacht, etwa indem Titel, Text und Button aller Karten als direkte Kinder in einen einzigen Container wanderten. Für Screenreader ging damit die Information verloren, welche Teile zu welcher Karte gehören. Mit Subgrid bleibt jede Karte ein eigenes, in sich geschlossenes Element (z.B. ein article), und die Ausrichtung übernimmt das gemeinsame Raster.
Ansonsten gilt dasselbe wie überall in Grid: Die visuelle Platzierung ändert weder die Tab- noch die Lesereihenfolge. Beide folgen der DOM-Reihenfolge (WCAG 1.3.2). Halte die DOM-Struktur logisch und nutze Subgrid nur für die visuelle Ausrichtung.
Häufige Fehler
5 Fehler 01 subgrid ohne eigenes display: grid
display: grid bleibt grid-template-columns: subgrid wirkungslos und die Kinder verhalten sich wie normale Block-Elemente. 02 Kein Grid-Item
03 Nur einen Track überspannt
grid-template-rows: subgrid setzt, aber das grid-row: span 3 vergisst, bekommt ein Subgrid mit genau einer Zeile, und alle Inhalte quetschen sich hinein. 04 Eigene Größen mit subgrid mischen
grid-template-columns: subgrid 200px 1fr ist ungültig, die komplette Deklaration wird verworfen. Track-Größen kommen immer vom Elterngrid, nach dem Schlüsselwort sind nur Liniennamen erlaubt. 05 Auf implizite Tracks hoffen
Browser-Kompatibilität
5 von 5Subgrid wird von allen modernen Browsern vollständig unterstützt, sowohl für Spalten als auch für Zeilen.
-
Chrome
Komplett
-
Firefox
Komplett
-
Safari
Komplett
-
Edge
Komplett
-
Opera
Komplett
Email-Kompatibilität
0 von 5Subgrid hat in HTML-Emails sehr eingeschränkten Support. Für E-Mail-Layouts solltest du auf Tabellen-basierte Layouts zurückgreifen.
-
Apple Mail
Teilweise
Grundlegender Grid- und Subgrid-Support vorhanden
-
Gmail
Keine
Grid wird komplett ignoriert
-
Outlook
Keine
Kein Grid-Support, Tabellen-Layouts verwenden
-
Thunderbird
Teilweise
Grundlegender Grid- und Subgrid-Support vorhanden
-
Yahoo Mail
Keine
Kein Grid-Support
Newsletter
einmal die Woche, kostenlosNeue Artikel und Videos, was sich auf der Lernplattform tut, und ab und zu ein Sonderpreis zum Kursstart. Kurz genug, dass du es auch liest.
Zuletzt verschickt · KW 40
Einmal alles neu, und die Lernplattform ist da