Rolf B: Anfänge mit GRID: HTML- und CSS-Sheets korrekt strukturieren

Beitrag lesen

Hallo einsiedler,

Geht dies auch mit dieser Schreibweise:

body {
 display: grid;

 grid: "main-head content content" 1fr auto auto
          "main-head content content" auto / 1fr auto auto;

Nun möchte ich in der ersten Zeile (ROW) beim zweiten content die Navigation überlagernd abbilden und im zweiten ROW beim letzten content den "To-Top"-Button.

Ja. Geht. Wird aber hässlich.

Zur Erklärung: Ein Grid besteht aus den Gridzellen, die in Zeilen und Spalten verteilt sind. Vor, zwischen und hinter den Zeilen und Spalten sind die Gridlinien. Wie hier gezeigt. Die Linien sind ab 1 nummeriert, d.h. bei 4 Spalten hast Du vertikale Gridlinien von 1-5.

Gridlinen können Namen bekommen. So ein Name kann "hugo" sein, aber auch "main-start" oder "main-end".

Liniennamen müssen nur in einer Richtung eindeutig sein. Es ist okay, wenn Du eine horizontale Linie "content-start" und eine vertikale Linie "content-start" hast.

Wenn Du für ein Element festlegst, wo es hin soll, kannst Du grid-area verwenden. Das ist eine Sammeleigenschaft für grid-row und grid-column. Die grid-area Eigenschaft hat viele Syntaxe. Eine ist grid-area: 1/2/3/4, was bedeutet: Beginne ab Zeilenlinie 1, ab Spaltenlinie 1, gehe bis Zeilenlinie 3, bis Spaltenlinie 4.

Man kann auch benannte Linien verwenden. grid-area: hugo / otto / foo / bar. Funktioniert, wenn Du entsprechende Linien festgelegt hast.

Und jetzt kommts. Wir haben bisher schändlich gelogen. Das Festlegen von Bereichsnamen mit der grid-Eigenschaft erzeugt in Wahrheit gar keine Bereiche! Es erzeugt Linien. Dein Beispiel würde diese Linien erzeugen:

Vertikal:
  main-head-start=1
  main-head-end=2
  content-start=2
  content-end=4
Horizontal:
  main-head-start=1
  main-head-end=3
  content-start=1
  content-end=3

D.h. zu jeder benannten Area gehören 2 horizontale und 2 vertikale Linien, die den Namen der Area zusammen mit -start oder -end tragen.

Das geht auch andersrum. Ich kann einfach die passenden Linien erzeugen. Und dann mit grid-area: foo; festlegen, dass die Zelle vertikal von foo-start bis foo-end und horizontal von foo-start bis foo-end geht. Immer beachten: horizontales foo-start und vertikales foo-start sind zwei verschiedene Dinge.

Wie mixt man Liniennamen mit benannten Bereichen?

Liniennamen definierst Du mit [name]. Oder mit [name1 name2 name3], wenn du einer Linie mehrere Namen geben willst. Das weißt Du.

Nun musst Du diese Definitionen exakt an der richtigen Stelle in der grid-Eigenschaft hinschreiben. Ich habe diese Stellen mal mit *1 bis *7 durchnummeriert.

body {
   display:grid;
   grid:    [*1]  "a   b   c"   1fr  [*2]
            [*3]  "d   e   f"   2fr  
                  "g   h   i"   3fr  [*4]
             /  [*5] 1fr [*6] 2fr [*6] 3fr [*7];

Das ist ein 3×3 Grid mit 9 benannten Bereichen. Von Hause aus hat es also bereits 36 Namen für Rasterlinien vergeben, von a-start bis i-end.

Du kannst jetzt beispielsweise an Stelle *1 [menu-start] hinschreiben. Diese Stelle befindet sich vor der ersten Zeile, entspricht also der horizontalen Rasterlinie 1. Wenn Du an Stelle *2 [menu-end] hinschriebest, wäre das nach der ersten Zeile, also Rasterlinie 2. Die Stelle *3 ist vor der zweiten Zeile, was ebenfalls Rasterlinie 2 ist. Und wenn Du an Stelle *4 einen Namen setzt, ist er unter der letzten Zeile.

Vertikale Rasterlinien legst Du dort fest, wo das Spaltentemplate steht, d.h. genau wie bei grid-template-columns.

Möchtest Du also eine benannte Gridzelle haben, die in Spalte 3 ist und die Zeilen 1-3 einnimmt, müsstest Du das im abcdefghi-Beispiel so machen:

body {
   display:grid;
   grid: [menu-start]  "a   b   c"   1fr
                       "d   e   f"   2fr  
                       "g   h   i"   3fr  [menu-end]
                    /  1fr 2fr [menu-start] 3fr [menu-end];

Und dann kann dein Menübereich einfach grid-area:menu sagen und ist in der ganzen dritten Spalte. Ob er über oder unter anderen Elementen ist, hängt von der HTML-Reihenfolge ab. Oder vom z-index.

Hat das geholfen?

Rolf

--
sumpsi - posui - obstruxi