subgrid – Karten, deren Zeilen wirklich auf einer Linie liegen
Drei Karten nebeneinander, jede mit Titel, Text und Knopf – und alles steht leicht versetzt, weil ein Titel zweizeilig ist. Mit subgrid teilen sich die Karten die Zeilen des Eltern-Grids, und alles sitzt bündig. Ohne feste Höhen, ohne JavaScript.
Das Problem kennst du, wenn du schon mal drei Angebots- oder Blogkarten nebeneinandergestellt hast: Eine Überschrift ist zweizeilig, die anderen einzeilig – und schon rutschen Text und Knopf in dieser einen Karte nach unten. Das Auge sieht das sofort, auch wenn es „nur" zwanzig Pixel sind.
Der alte Weg waren feste Höhen (min-height: 3.2em für den Titel) oder ein bisschen JavaScript, das die höchste Karte misst. Beides ist Pflege-Aufwand: Ändert sich die Schrift oder die Sprache, stimmt die Zahl nicht mehr.
Mit subgrid löst das CSS selbst.
Der Kern
.karten {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
/* Die Zeilen, die sich ALLE Karten teilen: Titel, Text, Fuß */
grid-template-rows: auto;
gap: 1.25rem;
}
.karte {
display: grid;
/* Statt eigener Zeilen: die Zeilen des Eltern-Grids übernehmen */
grid-template-rows: subgrid;
grid-row: span 3; /* so viele Zeilen, wie die Karte braucht */
gap: 0.75rem;
padding: 1.25rem;
border: 1px solid #d8dee9;
border-radius: 12px;
}<div class="karten">
<article class="karte">
<h3>Kurzer Titel</h3>
<p>Ein Satz.</p>
<a href="#">Mehr</a>
</article>
<article class="karte">
<h3>Ein deutlich längerer Titel, der umbricht</h3>
<p>Hier steht mehr Text als in der Karte daneben.</p>
<a href="#">Mehr</a>
</article>
</div>Wichtig ist die Kombination aus zwei Zeilen: grid-template-rows: subgrid sagt „ich mache keine eigenen Zeilen auf", und grid-row: span 3 sagt, wie viele Zeilen der Elternschiene die Karte belegt. Ohne das span weiß das Grid nicht, wie weit die Karte reicht.
Das Ergebnis: Die Titelzeile ist in allen Karten so hoch wie der längste Titel, die Textzeile so hoch wie der längste Text – und der Knopf steht überall auf derselben Höhe. Ganz ohne Zahl, die jemand pflegen müsste.
Der Stolperstein, der mich Zeit gekostet hat
subgrid funktioniert nur, wenn das Kind ein direktes Grid-Element des Elternteils ist. Packst du die Karte noch in einen <div> zum Zentrieren, ist die Kette unterbrochen und subgrid tut nichts – kommentarlos. Wenn es also nicht wirkt: Als Erstes prüfen, ob wirklich Eltern-Grid → Karte direkt aufeinanderfolgen.
Und gap gilt weiter für das Elternteil. Setzt du in der Karte ein anderes gap, überschreibt das die Abstände innerhalb der übernommenen Zeilen – das ist erlaubt und oft genau das, was man will.
Braucht das noch einen Fallback?
subgrid ist seit 2023 in allen großen Browsern (Firefox, Safari, Chrome, Edge). Wenn du noch sehr alte Stände bedienen musst, kannst du es sauber abstufen:
@supports (grid-template-rows: subgrid) {
.karte { grid-template-rows: subgrid; grid-row: span 3; }
}Ohne Unterstützung sehen die Karten aus wie vorher – leicht versetzt, aber vollständig lesbar. Das ist ein Fallback, mit dem ich gut leben kann.
Genau solche Kleinigkeiten sind es, die eine Seite „ordentlich" statt „irgendwie gebaut" aussehen lassen. Wenn du dir deine Seite mal daraufhin anschauen lassen willst, schreib mir über bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
Text nach drei Zeilen abschneiden – line-clamp statt JavaScript
Kartenlisten sehen nur dann ordentlich aus, wenn alle Vorschautexte gleich hoch sind. Das serverseitig auf 120 Zeichen zu kürzen geht schief, sobald die Karte schmaler wird – CSS kann das seit Jahren selbst.
grid-template-areas – ein Layout, das man im Code sehen kann
Statt Zeilen- und Spaltennummern zu zählen, malst du dein Layout als kleine ASCII-Zeichnung ins CSS. Auf dem Handy schreibst du die Zeichnung einfach anders – dieselben Bausteine, andere Anordnung, kein einziger geänderter HTML-Knoten.
accent-color – Checkboxen und Regler in deiner Markenfarbe, in einer Zeile
Checkboxen und Radiobuttons waren jahrelang der Grund, warum Leute sie mit appearance: none nachgebaut haben – und dabei die Tastaturbedienung verloren. Eine einzige CSS-Eigenschaft macht das überflüssig.