mitmario.dev

Projektraster und Seitenlayout

CSS Im Browser 3 Min Lesezeit 2 BeispieleLektion 8 von 9

Ein Seitenlayout mit Kopfzeile, Seitenspalte, Inhalt und Fußzeile, und im Inhalt ein Raster aus Projektkarten. Neue Eigenschaften braucht es dafür keine. Es sind zwei Raster ineinander.

Zwei Ebenen, zwei Techniken

Außen liegt das Seitenlayout mit benannten Bereichen aus 10.4, innen das Kartenraster mit auto-fit und minmax() aus 10.2. Beides ist Grid, und trotzdem sind es zwei verschiedene Werkzeuge für zwei verschiedene Fragen.

Ein Seitenlayout mit Seitenspalte braucht Breite, und die hat die schmale Spalte neben dem Editor nicht. Dort wird es eng. Die Seitenspalte behält ihre 160 Pixel, für den Inhalt bleiben rund 176, und die drei Karten werden schmal. Im Vollbild steht die Seite von allein auf den 900 Pixeln, für die die Beispiele gebaut sind, und die Bereiche liegen so, wie sie gemeint sind.

Der Unterschied liegt darin, was man im Voraus weiß.

  • Die Struktur der Seite steht fest. Es gibt eine Kopfzeile, eine Seitenspalte, einen Inhaltsbereich und eine Fußzeile, und diese vier bleiben, egal was passiert. Etwas Festes zeichnet man auf.
  • Die Zahl der Karten steht nicht fest. Heute sind es vier, morgen neun, und wie breit der Inhaltsbereich gerade ist, hängt vom Bildschirm ab. Etwas Unbekanntes lässt man ausrechnen.

Das innere Raster steht auf auto-fit, und deshalb ist es ihm egal, dass es in einem Inhaltsbereich neben einer Seitenspalte sitzt und nicht über die volle Seite geht. Es kennt seine eigene Breite. Mehr braucht es nicht.

Warum das äußere Raster keine Zeilenhöhen bekommt

Feste Zeilenhöhen im Seitenlayout
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 16px;
  font-family: system-ui, sans-serif;
  line-height: 1.5;
  background-color: #f4f4f5;
}

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

.seite {
  display: grid;
  grid-template-columns: 160px 1fr;
  grid-template-areas:
    "kopf kopf"
    "seitenspalte inhalt"
    "fuss fuss";
  gap: 12px;
  margin-bottom: 32px;
}

/* 120px für die mittlere Zeile, geraten beim
   Schreiben und falsch, sobald jemand einen Absatz
   ergänzt. */
.fest {
  grid-template-rows: 48px 120px 48px;
}

header,
footer {
  grid-area: auto;
  padding: 16px;
  font-weight: 700;
  color: #ffffff;
  background-color: #18181b;
}

.seite header {
  grid-area: kopf;
}

.seite aside {
  grid-area: seitenspalte;
}

.seite main {
  grid-area: inhalt;
}

.seite footer {
  grid-area: fuss;
}

aside {
  padding: 16px;
  font-weight: 700;
  color: #ffffff;
  background-color: #2563eb;
}

main {
  padding: 16px;
  background-color: #ffffff;
}

main p {
  margin: 0;
  color: #52525b;
}

Man ist versucht, zur Zeichnung auch gleich grid-template-rows zu schreiben. Ich lasse das.

Eine feste Zeilenhöhe ist eine Zahl, die du beim Schreiben rätst und die ab dem nächsten Absatz falsch ist. Im Beispiel sind 120px für die mittlere Zeile vorgesehen, und der Text läuft unten heraus. Wie bei festen Höhen sonst auch weiß der Inhalt besser, wie hoch er ist.

Im Streifen steht die Zahl unverändert da, und daran sieht man das Problem. Am Raster steht grid-template-rows: 48px 120px 48px, am Inhaltsbereich darin height: 120px. Der Text darin braucht mehr, und trotzdem bleibt es bei 120. Eine feste Zeile gibt nicht nach, sie lässt überlaufen. Ohne Zeilenhöhen stünden die Zeilen so hoch, wie ihr Inhalt sie braucht.

Bei den Spaltenbreiten ist das anders. 200px 1fr ist eine bewusste Entscheidung über das Layout, und die Seitenspalte soll wirklich 200px breit sein. Bei Zeilen gibt es diesen Grund fast nie.

Der Abstand als Gliederung

Außen trennt stärker als innen
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 16px;
  font-family: system-ui, sans-serif;
  background-color: #f4f4f5;
}

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

.seite {
  display: grid;
  margin-bottom: 32px;
}

.projekte {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

/* Derselbe Abstand auf beiden Ebenen macht die
   Gliederung unsichtbar: Karte, Kopf- und Fußzeile wirken
   gleich weit voneinander entfernt. */
.gleich {
  row-gap: 16px;
}

/* Ein größerer Abstand zwischen den Bereichen sagt,
   dass hier etwas anderes anfängt. */
.gestuft {
  row-gap: 48px;
}

header,
footer {
  padding: 16px;
  font-weight: 700;
  color: #ffffff;
  background-color: #18181b;
}

.projekt {
  padding: 24px;
  border-radius: 12px;
  font-weight: 700;
  color: #ffffff;
  background-color: #2563eb;
}

Im Beispiel steht das äußere Raster einmal auf 16px und einmal auf 48px, das innere immer auf 16px. Die zweite Fassung sieht sortiert aus, die erste nicht, und es ist derselbe Inhalt.

Nachsehen lohnt sich hier, weil sich sonst nichts unterscheidet. An den beiden äußeren Rastern steht im Streifen einmal gap: 16px normal und einmal gap: 48px normal. Die Zeilen sind in beiden 51px 67px 51px, die Spuren dieselben. Der ganze Unterschied ist eine Zahl.

Abstand gliedert. Die Lücke zwischen zwei Karten sagt “das gehört zusammen”, die Lücke zwischen Inhaltsbereich und Fußzeile sagt “hier fängt etwas anderes an”. Sind beide gleich groß, sagt keine von beiden etwas.

Deshalb darf der äußere gap größer sein als der innere, und deshalb lohnt sich eine Abstandsskala. Zwei Stufen Unterschied reichen meistens.

Flexbox in der Karte

Das Raster bringt die Karten an ihren Platz. Überschrift, Text und Button innerhalb einer Karte liegen aber nur auf einer Achse, und dafür ist Flexbox das einfachere Werkzeug. Erst wenn diese Teile über die Karten hinweg auf einer Linie stehen sollen, kommt subgrid dazu.

Wann du welches von beiden nimmst, darum geht es im nächsten Abschnitt.

In der Aufgabe fehlen beide Raster, das der Seite und das der Karten darin.

Zum Mitnehmen

Zwei Raster ineinander, zwei Techniken aus demselben Abschnitt. Außen benannte Bereiche, weil die Struktur der Seite feststeht. Innen auto-fit mit minmax, weil die Zahl der Karten und die verfügbare Breite es nicht tun.

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 2 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.