Hallo Michael,
ich habe Dich für Hintergrundinformationen aus gutem Grund an unser Wiki verwiesen.
Es gibt eine Menge Varianten, wie man ein Grid definieren kann. Dabei sind diese Aufgaben zu lösen:
- Wie breit ist welche Spalte
- Wie hoch ist welche Zeile
- Welches Grid-Item kommt in welchen Rasterbereich.
- Und dann kommen noch Optionen für automatische Platzierung und für automatisches Hinzufügen von Zeilen (oder Spalten).
grid-template-columns definiert Spaltenbreiten, grid-template-rows definiert Zeilenhöhen. Das hast Du verwendet.
Und dann hast Du deine Grid-Items mit grid-row/column-start/end platziert. Das kann man machen. Es ist nur nicht so gut lesbar. Und umständlich.
Eine Alternative sind benannte Grid-Bereiche. Dafür gibt es die Eigenschaft grid-template-areas. Ich habe grid-template verwendet, das ist eine Kurzform, die erkläre ich ganz zum Schluss.
Wenn Du ein Grid aus 5 Spalten und 3 Zeilen machen willst, dann gibtst Du für grid-template-areas
drei Zeichenketten an, eine pro Zeile. Und jede Zeichenkette enthält fünf Namen. Oder einen Punkt für unbenannte Bereiche. Die unabgekürzte Version sieht dann so aus:
body {
grid-template-areas: ". . losung logo ."
"y y stamm menü m-over"
". . stamm main .";
grid-template-rows: auto auto 1fr;
grid-template-columns: 1fr 3em 10em minmax(20em, 50em) 1fr;
}
.stamm
{
grid-area: stamm;
/* Die grid-area Angabe ersetzt das Folgende: */
grid-row-start: 2;
grid-row-end: 4
grid-column-start: 3;
grid-column-end: 4;
}
Ich habe also 3 Zeilen. Die Höhe der beiden ersten soll automatisch an Hand des Inhalts bestimmt werden, die dritte Zeile füllt den Rest der Höhe aus (1fr). Und ich habe 5 Spalten. Die zweite Spalte ist 3em breit, die dritte Spalte 10em, die vierte Spalte ist so breit wie möglich, aber mindestens 20em und höchstens 50em. Die Spalten 1 und 5 füllen den verbleibenden Platz. D.h. solange die Spalte 4 nicht 50em breit ist, haben die Spalten 1 und 5 die Breite 0. Und danach breiten sie sich aus und haben die gleiche Breite, d.h. der eigentliche Body in den Spalten 2 bis 4 wird dadurch horizontal zentriert.
Nun zu den template-areas. Wie gesagt, das sind drei Zeichenketten (also Text, der in Anführungszeichen steht), eine pro Zeile. Jede Zeichenkette enthält 5 Angaben für Spalten.
Zeile 1: Zwei Punkte, also kein benannter Bereich in Spalte 1 und 2. Dann losung
, Zeile 1, Spalte 3 hat also den Namen losung
. logo
ist in Zeile 1, Spalte 4. Und Spalte 5 ist wieder unbenannt.
Zeile 2: Wenn zwei Namen in diesen Zeichenketten gleich sind, macht das Grid einen zusammenhängenden Bereich daraus. Der Name y
nimmt in Zeile 2 also die Spalten 1 und 2 ein. Da soll kein Inhalt hinkommen, da soll nur ein Dummy-div zum Färben hin, darum heißt er nur y, du könntest ihn auch kain
oder kreuz-links
nennen. Mit der y-Achse hat das nichts zu tun - ich hatte die inhaltslosen Bereiche nur zuerst x, y und z genannt und dann x und z duch Punkte ersetzt. Der Name m-over
steht dann für "menu overflow", das ist das Gegenstück zum ersten y auf der linken Seite. Ich konnte aber menu und m-over nicht gleich nennen, denn ich möchte ja, dass das Menü im Hauptbereich bleibt und der m-over Bereich lediglich Farbe hat.
Zusammenhängende Bereiche können auchüber Zeilen hinweg gehen, das ist bei stamm
der Fall.
Du kannst auch Bereiche mit 2 Zeilen und 3 Spalten machen, kein Problem. Grid schreibt nur vor, dass solche Bereiche quadratisch oder rechteckig sein müssen[1]
Diese Namen sind Namen für Gridbereiche und haben mit Klassen oder HTML IDs nichts zu tun. Der nächste Schritt ist deshalb, HTML Elemente in benannten Gridbereichen zu platzieren. Das siehst Du darunter: Für Elemente mit der Klasse stamm
wird per grid-area festgelegt, dass sie im Gridbereich stamm
platziert werden sollen. Statt dessen könntest Du auch Zeilen und Spalten angeben, aber das ist lästig. Namen sind viel eleganter.
Und vor allem: wenn Du über eine @media Abfrage dein Layout umschalten willst, musst Du bei Verwendung von benannten Bereichen nur die templates umbauen. Die Grid-Items musst Du nicht mehr anfassen.
Und dann habe ich Mist gemacht. Ich habe nämlich gespart und es nicht erklärt. Das div mit Klasse balken
hat dieses CSS:
.balken {
grid-area: y-start / y-start / y-end / m-over;
}
Das ist kryptisch und - leider - inkonsistent.
Kryptik 1: Das grid-area Attribut kann mehrere Dinge tun. Es kann ein Element einem Bereich zuordnen, das war in dem .stamm Beispiel oben der Fall. Und es gibt die Version mit drei Schrägstrichen, dann ist es die Zusammenfassung von grid-row-start, grid-column-start, grid-row-end und grid-column-end - in dieser Reihenfolge.
Kryptik 2: Wenn ich einen benannten Bereich erstelle, dann erzeugt das Grid automatisch weitere Namen. Wenn ich den benannten Bereich y
habe und y-start
an einer Stelle hinschreibe, wo eine Spaltenangabe erwartet wird, dann steht y-start
für die Spalte, in der y startet. Also 1. Schreibe ich y-start
oder y-end
an einer Stelle hin, wo eine Zeile erwartet wird, ist das die Zeile, wo y
beginnt oder endet.
Inkonsistenz: Statt m-over
hätte ich m-over-end
schreiben müssen. Und nun kommt Magie hinzu, denn das habe ich gar nicht gewusst: Wenn ich m-over
an einer Stelle hinschreibe, wo eine End-Angabe erwartet wird, verwendet der Browser automatisch m-over-end
.
Besser wäre also gewesen:
.balken {
/* Von Zeile/Spalte bis Zeile/Spalte */
grid-area: y-start / y-start / y-end / m-over-end;
/* In Zahlen wäre das dies:
grid-area: 2 / 1 / 3 / 6;
*/
}
Und funktionieren würde auch jede der beiden folgenden grid-area Angaben:
.balken {
grid-area: y / y / y / m-over;
grid-area: y / y / m-over / m-over;
}
Der Browser denkt sich die passenden -start und -end automatisch dazu. Aber das ist dann schon höhere CSS Lehre. Es gibt noch mehr Möglichkeiten - aber ich habe sie nicht verstanden…
Und dann habe ich auch noch gespart: Ich hatte nämlich keine Lust, für die Füllbereich links und rechts jeweils ein eigenes DIV zu machen. Statt dessen gibt's nur eins, nämlich das mit der Klasse balken
. Und das geht in Zeile 2 von Spalte 1 bis Spalte 5. Im HTML steht es vor dem Stamm- und Menü-Teil, deswegen liegt es im Hintergrund (was später kommt, wird obendrauf gestapelt).
Bei der HTML Reihenfolge der übrigen Teile war ich möglicherweise fehlerhaft. Man sollte das HTML so anordnen, dass die Inhalte in der gewünschten Reihenfolge stehen, wenn man das CSS ganz weglässt. Das Grid erlaubt mir beliebige Platzierung, das kann schon mal zu falschen Anordnungen verleiten.
Das alles kannst Du so verwenden. Ich bin aber noch einen Schritt weitergegangen.
Kennst Du die Eigenschaft background
? Sie fasst 6 oder 7 Background-Eigenschaften zusammen. Genauso fasst grid-template
die drei Template-Eigenschaften zusammen, die ich im body benutzt habe. Und natürlich muss man die Angaben auf eine Weise zusammenmixen, die intuitiv ist.
body {
grid-template: ". . losung logo ." auto
"y y stamm menü m-over" auto
". . stamm main ." 1fr /
1fr 3em 10em minmax(20em, 50em) 1fr;
Du erkennst die Werte wieder? Die Namensbereiche für jede Zeile, hinter jedem Zeilenbereich steht die Zeilenhöhe. Und dann kommt ein / und danach die Spaltenbreiten. Das ist alles.
Rolf
sumpsi - posui - obstruxi
Jajaja, ich weiß, ein Quadrat ist ein Spezialfall eines Rechtecks, aber ich rede hier mit einem Theologen und nicht mit einem Mathematiker ↩︎