mitmario.dev

Wann Flex, wann Grid, wann beides

CSS Im Browser 4 Min Lesezeit 3 BeispieleLektion 1 von 5

Eine Werkzeugleiste mit vier Buttons sieht nach einer Reihe aus, also nach einem Raster mit vier Spalten. Baut man sie so, bricht „Als Entwurf sichern“ auf zwei Zeilen um, und „Neu“ steht in fast dreimal so viel Platz, wie es braucht. Wie Flexbox und Grid gehen, ist klar. Offen ist, wann welches passt.

Eine Achse gegen zwei

Eine Achse gegen zwei
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, sans-serif;
}

.titel {
  margin-bottom: 4px;
  font-size: 14px;
  color: #52525b;
}

/* Jede Marke ist so breit wie ihr Wort. Der Container
   reiht sie auf und lässt sie umbrechen. */
.reihe {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 24px;
}

/* Vier gleich breite Spalten, egal wie lang das Wort
   darin ist. Bei CSS bleibt viel Luft, bei
   Webperformance wird es eng. */
.raster {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 24px;
}

.marke {
  padding: 8px;
  border-radius: 999px;
  font-weight: 700;
  color: #ffffff;
  background-color: #2563eb;
}

Der technische Unterschied ist schnell gesagt. Flexbox verteilt auf einer Achse, Grid spannt zwei auf.

Nützlicher ist der Unterschied in der Denkrichtung.

  • Grid ordnet vom Container aus. Du legst fest, wo etwas hinkommt, und die Kinder fügen sich ein.
  • Flexbox ordnet vom Inhalt aus. Du sagst, wie die Kinder sich einigen sollen, und der Platz verteilt sich danach.

Im Beispiel siehst du dieselben vier Marken zweimal. Über der Seite steht „für 768 px“, und im Vollbild steht die Seite von allein auf diesen 768. Bei Flexbox ist jede Marke so breit wie ihr Wort. Bei Grid sind alle gleich breit, weil die Spalten es so vorgeben. Beides ist richtig, nur beantwortet es verschiedene Fragen.

Am unteren Raster steht dort im Auskunftsstreifen des Inspectors grid-template-columns: 182px 182px 182px 182px, viermal dieselbe Zahl, und jede Marke darin misst 182 × 35. Oben im Flex-Kasten misst „CSS“ rund 50 × 35 und „Webperformance“ rund 171 × 35. Das Raster gibt der kürzesten Marke mehr als dreimal so viel Platz, wie sie braucht, und der längsten gerade genug.

In der schmalen Spalte stehen dort vier verschiedene Zahlen, und das Raster läuft nach rechts aus dem Bild. 1fr verteilt nur den übrigen Platz. Ist keiner übrig, wird jede Spur bloß so breit wie ihr Inhalt, also genauso breit wie bei Flexbox. Dann sehen beide Kästen gleich aus. Deshalb steht die Breite darüber.

Lässt sich das Layout vorher auf ein Blatt zeichnen, nehme ich Grid. Bestimmt der Inhalt, wie viel Platz er braucht, nehme ich Flexbox.

Wo Flexbox gewinnt

Wo Flexbox gewinnt
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, sans-serif;
}

.titel {
  margin-bottom: 4px;
  font-size: 14px;
  color: #52525b;
}

.leiste {
  gap: 8px;
  margin-bottom: 24px;
  padding: 8px;
  background-color: #f4f4f5;
}

/* Vier Buttons, vier gleich breite Spuren. Der kurze
   hat zu viel Platz, der lange zu wenig. Ein Raster
   will hier gar niemand. */
.raster {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.flex {
  display: flex;
  flex-wrap: wrap;
}

button {
  padding: 8px 16px;
  border: 0;
  border-radius: 8px;
  font: inherit;
  font-weight: 700;
  color: #ffffff;
  background-color: #18181b;
}

Zurück zur Werkzeugleiste vom Anfang. Ihre Beschriftungen sind unterschiedlich lang. Ein Raster mit vier gleichen Spuren gibt “Neu” zu viel Platz und “Als Entwurf sichern” zu wenig. Hier weiß der Inhalt besser, wie breit er sein muss, und dafür ist Flexbox gebaut.

Auch dieses Beispiel ist für 768 gebaut. Bei dieser Breite stehen im Streifen oben viermal 178px, und jeder Button darin misst 178 × 54, ist also zwei Zeilen hoch. Unten in der Flex-Fassung misst „Als Entwurf sichern“ rund 208 × 35. Oben fehlen ihm also rund dreißig Pixel, und die kosten ihn eine ganze Zeile. „Neu“ misst dort rund 68 × 35 und ist damit rund ein Drittel so breit wie seine Spur im Raster.

Dasselbe gilt für Schlagwort-Listen, Navigationen und alles, was umbrechen soll, ohne dass die Umbruchstelle vorher feststeht.

Wo Grid gewinnt

Wo Grid gewinnt
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, sans-serif;
}

.titel {
  margin-bottom: 4px;
  font-size: 14px;
  color: #52525b;
}

.plan {
  margin-bottom: 24px;
  padding: 8px;
  background-color: #f4f4f5;
}

/* Jede Zeile ist ein eigener Flex-Container und weiß
   nichts von den anderen. Der Ort rutscht deshalb in
   jeder Zeile woanders hin. */
.flex .zeile {
  display: flex;
  gap: 12px;
  margin-bottom: 8px;
}

/* Ein Raster über alle neun Zellen. Die Spalten sind
   über alle Zeilen hinweg dieselben. */
.raster {
  display: grid;
  grid-template-columns: 60px 1fr auto;
  gap: 8px 12px;
}

.plan span {
  padding: 4px 8px;
  background-color: #ffffff;
}

Und hier ist es andersherum. Ein Zeitplan aus mehreren Zeilen zu je drei Angaben sieht nach “eine Zeile ist eine Flex-Reihe” aus. Baut man es so, rechnet jede Zeile für sich. Die Spalten fluchten nicht, und der Ort steht in jeder Zeile an einer anderen Stelle.

Diesmal brauchst du keine besondere Breite, der Unterschied ist auch in deiner Spalte zu sehen. Im oberen Kasten misst „Saal A“ im Inspector rund 61 in der Breite, „Werkstatt 2“ rund 109 und „Saal B“ rund 58. Drei Zeilen, drei Breiten. Das Thema davor ist in jeder Zeile anders lang, also fängt auch der Ort jedes Mal woanders an.

Ein Raster über alle Zellen löst das, denn seine Spalten sind über die Zeilen hinweg dieselben. Im unteren Kasten misst jeder der drei Orte rund 109, und am Container steht auch, woher die Zahl kommt. Bei grid-template-columns stehen dort bei der Breite, mit der die Spalte startet, gerundet 60px 155px 109px, und die mittlere Zahl wächst mit der Spalte. Im Stylesheet steht 60px 1fr auto, im Streifen stehen die Zahlen, die der Browser daraus gerechnet hat. Die dritte Spur ist so breit wie der längste Ort, und alle drei bekommen sie.

Sobald etwas über mehrere Zeilen hinweg auf einer Linie stehen soll, ist es eine Aufgabe für Grid. Flexbox hat dafür keine Möglichkeit, denn ein Flex-Container kennt seinen Nachbarn nicht. Bei subgrid in 10.7 ging es um dasselbe, nur eine Ebene tiefer.

Flex und Grid ineinander

In der Praxis fragt man selten “Flex oder Grid” für die ganze Seite. Die Frage stellt sich für jede Ebene einzeln, und ein typisches Projekt sieht so aus.

  • Die Seite ist ein Grid mit benannten Bereichen.
  • Die Kopfzeile darin ist eine Flex-Reihe, weil Logo und Navigation sich den Platz teilen.
  • Das Projektraster ist ein Grid mit auto-fit.
  • Die Karte darin ist eine Flex-Spalte, damit der Button unten sitzt.
  • Die Werkzeugleiste in der Karte ist eine Flex-Reihe mit Umbruch.

Fünf Ebenen, fünfmal die Frage neu gestellt, zweimal mit Grid beantwortet und dreimal mit Flexbox. Die beiden Raster hast du in 10.8 gebaut, Kopfzeile und Karte schon in Abschnitt 9.

In der Aufgabe stehen zwei Bereiche der Projektseite noch als schlichte Blöcke da, und welche Technik wohin gehört, musst du selbst entscheiden.

Zum Mitnehmen

Beim Raster entscheidet der Container, bei Flexbox der Inhalt. Was über mehrere Zeilen hinweg auf einer Linie stehen soll, gehört in ein Raster, was sich seinen Platz nach dem Inhalt nimmt, in eine Flex-Reihe. In fast jedem Projekt liegen beide ineinander.

Jetzt du

Basis Konto, kostenlos

Zu 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 3 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.