Abschnitt 10 · Lektion 7
subgrid
Wenn drei Karten gleich hoch sind und ihren Button unten haben, sieht das schon ordentlich aus. Innen steht trotzdem noch nichts auf einer Linie. Dafür gibt es eine eigene Eigenschaft.
Gleich hoch, innen schief
<div class="projekte">
<article class="projekt">
<h3>Tipptrainer</h3>
<p>Zehnfinger im Browser, ohne Anmeldung.</p>
<a class="button" href="#">Ansehen</a>
</article>
<article class="projekt">
<h3>Referenz für HTML und CSS</h3>
<p>Mit Beispielen und ihrem Ergebnis gleich darunter.</p>
<a class="button" href="#">Ansehen</a>
</article>
<article class="projekt">
<h3>Newsletter</h3>
<p>Jeden Freitag ein Thema aus der Webentwicklung, kurz gehalten und ohne Werbung.</p>
<a class="button" href="#">Ansehen</a>
</article>
</div> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
background-color: #f4f4f5;
}
/* Die Karten sind gleich hoch, dafür sorgt das Raster.
Innen ist jede für sich: Überschrift, Text und Button
stehen dort, wo der jeweils vorige Teil aufhört. */
.projekte {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.projekt {
padding: 16px;
border-radius: 12px;
background-color: #ffffff;
}
.projekt h3 {
margin: 0 0 8px 0;
font-size: 18px;
}
.projekt p {
margin: 0 0 12px 0;
color: #52525b;
}
.button {
display: inline-block;
padding: 8px 16px;
border-radius: 8px;
font-weight: 700;
text-decoration: none;
color: #ffffff;
background-color: #2563eb;
} Die drei Karten im Beispiel sind gleich hoch. Innen ist trotzdem nichts aneinander ausgerichtet. Die Überschrift der mittleren Karte bricht um, deshalb fängt ihr Text tiefer an als bei den Nachbarn. Und der Button sitzt in jeder Karte woanders.
Jedes Grid-Kind hat sein eigenes, unabhängiges Raster. Die Karte weiß nicht, dass ihre Nachbarn auch eine Überschrift haben. Sie stapelt einfach ihre drei Teile, jeder so hoch, wie er eben ist.
Die Spuren des Elternteils übernehmen
<div class="projekte">
<article class="projekt">
<h3>Tipptrainer</h3>
<p>Zehnfinger im Browser, ohne Anmeldung.</p>
<a class="button" href="#">Ansehen</a>
</article>
<article class="projekt">
<h3>Referenz für HTML und CSS</h3>
<p>Mit Beispielen und ihrem Ergebnis gleich darunter.</p>
<a class="button" href="#">Ansehen</a>
</article>
<article class="projekt">
<h3>Newsletter</h3>
<p>Jeden Freitag ein Thema aus der Webentwicklung, kurz gehalten und ohne Werbung.</p>
<a class="button" href="#">Ansehen</a>
</article>
</div> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
background-color: #f4f4f5;
}
.projekte {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 16px;
row-gap: 8px;
}
/* Drei Teile, also drei Zeilen des Elternteils. Ohne
das span wüsste der Browser nicht, wie viele Spuren
die Karte übernehmen soll. */
.projekt {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
padding: 16px;
border-radius: 12px;
background-color: #ffffff;
}
.projekt h3 {
margin: 0;
font-size: 18px;
}
.projekt p {
margin: 0;
color: #52525b;
}
.button {
justify-self: start;
padding: 8px 16px;
border-radius: 8px;
font-weight: 700;
text-decoration: none;
color: #ffffff;
background-color: #2563eb;
} Mit grid-template-rows: subgrid legt die Karte keine eigenen Zeilen an, sondern benutzt die des Elternteils. Alle großen Browser können das seit September 2023, Chrome als letzter mit Version 117.
Damit das aufgeht, braucht die Karte so viele Zeilen, wie sie Teile hat. Sie hat Überschrift, Text und Button, also drei, und deshalb steht dazu grid-row: span 3. Ohne das wüsste der Browser nicht, wie viele Spuren er übernehmen soll.
<div class="projekte">
<article class="projekt">
<h3>Tipptrainer</h3>
<p>Zehnfinger im Browser, ohne Anmeldung.</p>
<a class="button" href="#">Ansehen</a>
</article>
<article class="projekt">
<h3>Referenz für HTML und CSS</h3>
<p>Mit Beispielen und ihrem Ergebnis gleich darunter.</p>
<a class="button" href="#">Ansehen</a>
</article>
<article class="projekt">
<h3>Newsletter</h3>
<p>Jeden Freitag ein Thema aus der Webentwicklung, kurz gehalten und ohne Werbung.</p>
<a class="button" href="#">Ansehen</a>
</article>
</div> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
background-color: #f4f4f5;
}
.projekte {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 16px;
row-gap: 8px;
}
/* Hier fehlt das span. Die Karte bekommt eine
einzige Zeile des Elternteils und übernimmt
nur diese eine Spur. */
.projekt {
display: grid;
grid-template-rows: subgrid;
padding: 16px;
border-radius: 12px;
background-color: #ffffff;
}
.projekt h3 {
margin: 0;
font-size: 18px;
}
.projekt p {
margin: 0;
color: #52525b;
}
.button {
justify-self: start;
padding: 8px 16px;
border-radius: 8px;
font-weight: 700;
text-decoration: none;
color: #ffffff;
background-color: #2563eb;
} Fehlt die Zeile, bekommt die Karte nur eine Zeile des Elternteils, und ihr eigenes Raster hat genau eine Spur. Überschrift, Text und Button landen alle darin. Sie liegen übereinander, in jeder Karte an derselben Stelle.
Mit der Zeile teilen sich alle drei Karten dieselben drei Zeilen. Die Zeile für die Überschriften ist so hoch wie die höchste Überschrift, die für den Text so hoch wie der längste Text. Jede Karte liegt in denselben Spuren, und damit stehen Überschriften, Texte und Buttons jeweils auf einer Linie.
Im Streifen steht das hier ausnahmsweise nicht in Pixeln. An einer Karte steht im Reiter „Werte“ grid-template-rows: subgrid [] [] [] [], also das Schlüsselwort selbst und dahinter die vier Linien, die sie vom Elternteil übernimmt. Überall sonst in diesem Abschnitt rechnet der Browser die Spuren in Pixel um. Hier gibt es nichts umzurechnen, denn die Karte hat gar keine eigenen Zeilen. Im Beispiel darüber ist dieselbe Karte übrigens nicht einmal ein Raster, dort steht display: block.
Für Spalten gibt es das Gleiche mit grid-template-columns: subgrid. Das brauchst du seltener, das Muster ist aber dasselbe.
Die Abstände zwischen den Spuren kommen dabei vom Elternteil mit. Deshalb steht im Beispiel row-gap: 8px am äußeren Raster, und dieser Abstand liegt in jeder Karte zwischen Überschrift, Text und Button.
Dieselben Karten mit Flexbox
<p class="titel">Flex-Spalte mit margin-top: auto</p>
<div class="projekte">
<article class="projekt">
<h3>Tipptrainer</h3>
<p>Zehnfinger im Browser, ohne Anmeldung.</p>
<a class="button" href="#">Ansehen</a>
</article>
<article class="projekt">
<h3>Referenz für HTML und CSS</h3>
<p>Ein Text mittlerer Länge.</p>
<a class="button" href="#">Ansehen</a>
</article>
<article class="projekt">
<h3>Newsletter</h3>
<p>Noch ein Text.</p>
<a class="button" href="#">Ansehen</a>
</article>
</div>
<p class="hinweis">
Die Buttons stehen auf einer Linie, das kann Flexbox. Die Absätze
nicht: in der mittleren Karte fängt der Text eine Zeile tiefer an,
weil die Überschrift darüber umbricht.
</p> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
background-color: #f4f4f5;
}
.titel {
margin-bottom: 4px;
font-size: 14px;
color: #52525b;
}
.projekte {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.projekt {
display: flex;
flex-direction: column;
padding: 16px;
border-radius: 12px;
background-color: #ffffff;
}
.projekt h3 {
margin: 0 0 8px 0;
font-size: 18px;
}
.projekt p {
margin: 0 0 12px 0;
color: #52525b;
}
.button {
margin-top: auto;
align-self: flex-start;
padding: 8px 16px;
border-radius: 8px;
font-weight: 700;
text-decoration: none;
color: #ffffff;
background-color: #2563eb;
}
.hinweis {
max-width: 60ch;
color: #52525b;
} Den Button hast du in 9.8 schon nach unten bekommen. Im Beispiel steht diese Lösung, und die Buttons stehen dort auf einer Linie.
Die Absätze aber nicht. In der mittleren Karte fängt der Text tiefer an, weil die Überschrift darüber umbricht.
Für zwei Teile pro Karte reicht Flexbox völlig. Sobald du drei oder mehr Ebenen hast, die über die Karten hinweg auf einer Linie stehen sollen, ist subgrid das einzige Mittel, das ohne feste Höhen auskommt.
In der Aufgabe tragen die Karten noch eine Rubrik über der Überschrift, und innen sitzt nichts auf einer Linie.
Zum Mitnehmen
Ein Grid-Kind hat normalerweise sein eigenes, unabhängiges Raster. subgrid ist die Ansage, stattdessen die Spuren des Elternteils zu übernehmen. Damit richten sich nicht nur die Karten aneinander aus, sondern auch ihre Innenteile.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.