CSS/Tutorials/Grid/benannte Linien und Rasterbereiche

Aus SELFHTML-Wiki
< CSS‎ | Tutorials‎ | Grid
Wechseln zu: Navigation, Suche

Bei jedem Raster stellt sich die Frage nach der optimalen Anzahl und der Identifizierung der einzelnen Rasterelemente. Im Schach werden die Spalten mit den Buchstaben a-h, die Reihen oder Zeilen mit 1-8 gekennzeichnet. Im Printbereich hat sich ein 12er-Raster (wie im letzten Kapitel erwähnt) bewährt, da es durch 2,3,4,6 teilbar ist und so viele verschiedene Kombinationen erlaubt.

Im WebDesign geht es eben aber nicht um ein Design für eine bestimmte Größe mit einem bestimten Seitenverhältnis, sondern um ein Design für eine Vielzahl von Viewports.

Deshalb wäre es gut, Rasterbereiche und ihre Rasterlinien nicht aufgrund ihrer Position, sondern mit ihrer semantischen Bedeutung kennzeichnen zu können. So kann das Seitenlayout in einem schnell zu erfassenden ASCII-Schema im CSS festgelegt werden.

Rasterbereiche

In vielen Tutorials wird ein Vorteil von Grid Layout herausgestellt: Die Positionierung kann auch allein im Elternelement des Grid Containers vorgenommen werden:

Grundraster mit festgelegten Rasterbereichen So sieht's aus
body{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-areas: "head head head head"
                       "nav  main main news"
                       "nav  main main aside" 
                       "foot foot foot foot";
}

header {
  grid-area: head;	
}

nav {
  grid-area: nav;			
}

article {
  grid-area: main;				
}
aside {
  grid-area: aside;			
}

#news {
  grid-area: news;			
}

Die Kindelemente (Grid Items) erhalten in der grid-area-Eigenschaft einen Namen, der dann in grid-template-areas in einem Schema wieder auftaucht. In diesem Schema werden wie in einer ASCII-Zeichung die einzelnen Elemente des Rasters aufgeführt.

Allerdings müssen die beiden aside-Boxen jetzt gesondert aufgeführt werden, da sie sich sonst überschreiben würden.


Anpassungen an andere Viewports

Mit dieser Methode können Anpassungen an andere Viewports sehr schnell vorgenommen werden:

responsives Raster So sieht's aus
body{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-areas: "head head "
                       "nav  nav"
                       "main main"
                       "news aside" 
                       "foot foot";
}

@media (min-width: 30em) { 
  body{
    grid-template-columns: repeat(3, 1fr);
    grid-template-areas: "head head head "
                         "nav  news aside"
                         "main main main" 
                         "foot foot foot";
 }
}

@media (min-width: 50em) { 
  body{
    grid-template-columns: repeat(4, 1fr);
    grid-template-areas: "head head head head"
                         "nav  main main news"
                         "nav  main main aside" 
                         "foot foot foot foot";
 }
}

Die Kindelemente sind bis auf die beiden aside-Boxen untereinander angeordnet Bei einer Viewportgröße von mindestens 30em greift die media query und schaltet die entsprechenden Werte für grid-template-areas um, sodass Navigation und aside-Boxen nebeneinander dargestellt werden. Ab 50em Breite wird das „normale“ Desktop-Layout erzeugt.

feststehender Footer in der Desktopansicht

Was im Grid Layout anfangs sehr verwirrt, ist die Vielzahl von gleichklingenden Eigenschaften. So wie grid-row-start zu shorthand grid-row und dann sogar zu grid-area zusammengefasst werden kann, können die Eigenschaften grid-template-columns, grid-template-rows und grid-template-areas in der zusammenfassenden Eigenschaft grid-template notiert werden. Aber auch diese ist Teil der zusammenfassenden Eigenschaft grid:

responsives Raster mit feststehenden Footer in der Desktopversion So sieht's aus
body{
  min-height: 100vh;
  display: grid;
  grid: "head head "
        "nav  nav"
        "main main"
        "news aside" 
        "foot foot"
        / 1fr 1fr;
}

@media (min-width: 30em) { 
  body{
    grid: "head head head "
          "nav  news aside"
          "main main main" 
          "foot foot foot"
          / 1fr  1fr 1fr;
 }
}

@media (min-width: 50em) { 
  body{
    grid: "head head head head" 150px
          "nav  main main news"   1fr
          "nav  main main aside"  1fr
          "foot foot foot foot" min-content
          / 1fr  1fr  1fr  1fr;
 }
}

In diesem Beispiel ist der body mit einer min-height von 100vh ausgestatttet, sodass er auch auf großen Monitoren immer bis ganz nach unten reicht.

Die Festlegungen der grid-template-areas und grid-template-columns werden nun in der zusammenfassenden Eigenschaft grid kürzer notiert. Beachten Sie, dass die Verwendung der repeat()-Funktion hier nicht möglich ist und die Spalten nacheinander ausgeschrieben werden müssen.

In den beiden schmalen Ansichten werden die Zeilen implizit erzeugt, in der dritten Ansicht erhält die ASCII-Zeichnung des Rasteraufbaus auf der rechten Seite Höhenangaben. Während der header einen festen Werte erhält, passt sich der footer mit min-content an den vorhandene Inhalt an und kann so nie das Layout zerschießen. Die beiden mittleren Zeilen verteilen sich über den verfügbaren restlichen Raum.

benannte Linien

In einem früheren Kapitel zeigten wir bereits, wie Sie Anfangs- und Endlinien festlegen können. Mit grid-column und grid-row können Sie Grid-Items innerhalb des Rasters positionieren:

  • grid-column: 1 / 6;: Das Rasterelement erstreckt sich von der ersten bis zur 6. Rasterlinie.
  • grid-column: 1 / -1;: Es sind auch negative Werte möglich. Das Rasterelement erstreckt sich von der ersten bis zur letzten Rasterlinie.

Grid-1.svg

Schwierig wird es, wenn sich das Raster ändert, wenn z. B. eine neue Spalte eingefügt wird.


Grid Layout bietet zusätzlich eine Alternative, die ganz ohne Mathematik auskommt! Anstelle von numerischen Werten können Sie den Rasterlinien auch semantische Namen geben, die das Positionieren der einzelnen Elemente ganz ohne Berechnungen erlaubt.[1][2]

Als Namen sind einerseits von Ihnen gewählte Zeichenketten erlaubt, noch einfacher ist andererseits das Verwenden der impliziten Namen:

Grid-3.svg

Die Rasterlinien am Anfang einer grid-area können mit …-start , am Ende mit …-end aufgerufen werden. Umgekehrt erzeugen benannte Rasterlinien im CSS implizit auch eine solche grid-area:

zentriertes Holy-Grail-Layout

zentriertes Holy-Grail-Layout mit benannten Linien So sieht's aus
@media (min-width: 45em) { 
	body{
	  display: grid;
	  grid-template-columns: 1fr [nav-start] fit-content(12em) [main-start] minmax(20em, 1fr)  [main-end] fit-content(15em)  [aside-end] 1fr;
	  grid-template-rows: [head-start] min-content 
	                      [main-start] 1fr 
	                      [main-end]   min-content 
	                      [foot-end];
	}
	header, footer {
	  grid-column: nav-start / aside-end;
	}
	nav {
	  grid-column: nav-start / main-start;
	}	
	main {
	  grid-column: main-start / main-end;
	  grid-row:    main-start / main-end;
	}
}

Der body wird mit dem schon bekannten grid-template-columns in 3 Spalten eingeteilt. Diese Inhaltsspalten erhalten keine feste Breite wie im pixelgenauen Layout, sondern mit fit-content() , bzw. minmax(20em, 1fr) flexible, an den Inhalt angepasste Breiten. auch die Höhe von header und fpooter wird mit min-content so festgelegt, dass immer genügend Platz für die Inhalte ist.

Die Werte für die Breiten werden jetzt nicht durch Leerzeichen, sondern durch in eckigen Klammern befindliche Liniennamen getrennt. Zusätzlich werden vor [nav-start] und nach [aside-end] Spalten erzeugt, die den Seiteninhalt zentrieren, sonst aber leer bleiben.

Auch für die Zeilen werden mit grid-template-rows Liniennamen vergeben. Hier fällt auf, dass die oberste und unterste Reihe durch das Schlüsselwort min-content so klein wie möglich dargestellt werden sollen.

Die Kindelemente erhalten nun ihre Positionierungen. Anstelle eines Ausrechnens der Breiten und Höhen werden als Beginn und Ende der Elemente aber benannte Linien verwendet.

Rasterlinien mit mehreren Namen

Der Name content-end als Beginn des footers mag verwirrend sein. Deshalb können Sie Rasterlinien mehrere Namen geben:

benannte Linien mit mehreren Namen
body {
	display: grid;
	grid-template-columns: [nav-start]                  1fr
	                       [content-start]              2fr 
	                       [content-end footer-start]   1fr [footer-end outer-end];
  	grid-template-rows: [top] 1fr 1fr 1fr [bottom];
}	

footer {
  grid-column: footer-start / footer-end;
  grid-row: 3 / bottom;
}

Innerhalb der eckigen Klammern können mehrere, durch Leerzeichen getrennte, Liniennamen notiert werden.

Mehrere Rasterlinien mit dem gleichen Namen

Dieses Szenario tritt ein, wenn Sie die repeat()-Funktion im Zeilen- oder Spalten-Template verwenden und darin einen Liniennamen setzen. Um festzulegen, die wievielte Linie dieses Namens Sie meinen, geben Sie die Liniennummer hinter dem Namen an:

benannte Linien mit mehreren Namen
body {
	display: grid;
	grid-template-columns: [nav-start]                  10em
	                       repeat(3, [content] 1fr)
  	grid-template-rows: auto;
}
section:nth-of-type(1) {
   grid-column: content 1 / span 1;
}
section:nth-of-type(2) {
   grid-column: content 2 / span 1;
}
section:nth-of-type(3) {
   grid-column: content 3 / span 1;
}

Anwendungsbeispiele

Navigation als Kreuz

Im CSS-Einstieg gibt es ein Beispiel, in dem als Dekoration ein Querbalken (engl. rule) eingefügt werden soll:


Grid Layout mit Pseudoelement zur Dekoration So sieht's aus
:root {
	--navWidth: 12em;
	--mainWidth: min(48em, calc(100% - var(--navWidth)));
	--headerLineHeight: 3em;
}

@media (min-width: 30em) {
  body { 
    display: grid;  
    grid-template:  ". nav head ." min-content
				    ". nav rule ." var(--headerLineHeight)
				    ". nav main ." auto
				    ". nav foot ." min-content /
				1fr var(--navWidth) var(--mainWidth) 1fr;
    } 
    body::before {
        content: '';
        grid-row: rule;
	grid-column: 1 / 1;
        background: linear-gradient(to right, var(--accent1), var(--accentlighter1));
    }
    body::after {
        content: '';
        grid-row: rule;
        grid-column: rule-start / -1;
        background-image: linear-gradient(to right, var(--accentmedium1), var(--accent1));
    }
}

Formular

Formulare müssen klar und übersichtlich sein. Häufig wurde die Gestaltung durch zahlreiche wrapper-Elemente und Zeilenumbrüche erreicht. Mit dem Grid Layout können Sie nun alle Formular-Elemente an einem Raster ausrichten:

form {
  display: grid;
  grid-template-columns: [labels] auto [controls] auto [oversized] auto;
  grid-auto-flow: row dense;
}
form > label {
  grid-column: labels;
  grid-row: auto;
}
form > input, form > select {
  grid-column: controls;
  grid-row: auto;
}
#department-block {
  grid-row: span 3;
  grid-column: oversized;
}

#buttons {
  grid-row: auto;
  grid-column: 1 / -1;
  text-align: end;
}
Das Formular form wird zu einem Raster mit drei Spalten, deren Größe inhaltsbasiert ist. Die entsprechende Rasterlinien erhalten aussagekräftige Namen.

Alle label-Elemente werden in die label-Spalte platziert; mit grid-row: auto; werden sie automatisch auf die Zeilen verteilt.
Analog wird mit den Eingabeelementen verfahren, die in der controls-Spalte platziert werden.
Das select-Menü mit der id department-block wird in die oversized-Spalte positioniert und umspannt dort 3 Zeilen (Auf mobilen Geräten wird das select-Menü durch ein Popup mit radio-Buttons ersetzt.)

Die Buttons werden von einem div umschlossen, das sich wegen grid-column: 1 / -1; über die gesamte Breite des Rasters erstreckt.

Periodensystem der Elemente

Die chemischen Elemente sind in einer Liste, die im Periodensystem nach steigender Kernladungszahl angeordnet sind. Dabei gibt es je nach Anzahl der Elektronen auf der Schale bestimmte Abstände.

Dies hat Gunnar Bittersmann in einem Pen mit grid-row und grid-column positioniert. Die Zahlen innerhalb der nth-of-type-Selektoren entsprechen der jeweiligen Ordnungszahl des Elements.

Anordnung und Lücken im Periodensystem
#periodic-table li:nth-of-type(2)
{
	grid-column: 18;
}

#periodic-table li:nth-of-type(5),
#periodic-table li:nth-of-type(13)
{
	grid-column: 13;
}

#periodic-table li:nth-of-type(n+58):nth-of-type(-n+71)
{
	grid-row: lanthanides;
}

#periodic-table li:nth-of-type(n+90):nth-of-type(-n+103)
{
	grid-row: actinides;
}

Fazit

Mit den benannten Linien und mehr noch, mit den ASCII-Rastern können Sie das Layout Ihrer Webseite mit wenigen Zeilen CSS festlegen und über media queries entsprechend aktivieren. Allerdings müssen Sie bei komplexeren Layouts oder anders aufgebauten Unterseiten neue Raster anlegen.


Weblinks

  1. MDN: Layout using named grid lines
  2. CSS-tricks: Using Grid Named Areas to Visualize (and Reference) Your Layout von Preethi Selvam on Aug 26, 2022