Dinge, die ich über CSS Grid Layout gelernt habe

Avatar of Ollie Williams
Ollie Williams am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der folgende Beitrag ist ein Gastbeitrag von Oliver Williams. Oliver arbeitet mit CSS Grid Layout und hat auf diesem Weg einiges gelernt. In diesem Artikel wird er verschiedene Konzepte vorstellen, die er auf dieser Reise gelernt hat. Mir gefällt die Idee, kleine, mundgerechte Lerneinheiten über Grid Layout durch isolierte Beispiele zu vermitteln, wo immer möglich. Das macht das Erlernen des Ganzen etwas weniger einschüchternd.

CSS Grid soll Anfang 2017 in Browsern erscheinen. Bis dahin müssen Sie Grid aktivieren, damit es funktioniert (außer in Firefox Nightly, wo es standardmäßig aktiviert ist). Chrome Canary hat derzeit die beste Implementierung. In der Zwischenzeit bietet Firefox ein unschätzbar wertvolles Add-on namens CSS Grid Inspector, das die Linien Ihres Grids anzeigen kann. Es ist derzeit der einzige Browser, der ein solches Tool besitzt.

Geben Sie in Chrome `chrome://flags` in Ihre Adressleiste ein, suchen Sie nach „Experimentelle Webplattform-Funktionen aktivieren“ und klicken Sie auf „Aktivieren“. IE und Edge haben alte Implementierungen, die von der aktuellen Spezifikation abweichen, und sind daher zu diesem Zeitpunkt nicht für Experimente mit Grid zu empfehlen.

Sie können keine Tetris-förmigen Grid-Bereiche haben

Das werden Sie schnell selbst herausfinden.

Ihre Grid-Bereiche können nur Rechtecke sein (wie links), keine beliebigen Polygone (wie rechts).

Grid ist dafür konzipiert, mit Flexbox verwendet zu werden, nicht anstelle von ihr

Grid und Flexbox können auf ähnliche Weise funktionieren. Sie haben vielleicht schon gesehen, wie Leute Flexbox zur Erstellung von Grid-Systemen verwenden, aber das ist nicht das, wofür Flexbox entwickelt wurde. Es lohnt sich, Jake Archibalds Blogbeitrag Verwenden Sie Flexbox nicht für das allgemeine Seitenlayout zu lesen.

Eine schnelle Art, es zu denken, ist:

  • Flexbox ist für eindimensionale Layouts (Zeile oder Spalte).
  • CSS Grid ist für zweidimensionale Layouts.

Oder wie Rachel Andrews es formulierte:

Flexbox ist im Wesentlichen für das Layout von Elementen in einer einzigen Dimension – in einer Zeile ODER einer Spalte. Grid ist für das Layout von Elementen in zwei Dimensionen – Zeilen UND Spalten.

Sie können auch kombiniert werden. Sie können ein Grid-Element in einen Flex-Container umwandeln. Sie können ein Flex-Element in ein Grid umwandeln.

Nehmen wir ein nützliches Beispiel. Wir möchten den Text innerhalb eines Grid-Elements vertikal zentrieren, aber der Hintergrund (ob Farbe, Farbverlauf oder Bild) soll den gesamten Grid-Bereich des Elements bedecken. Wir können die Eigenschaft align-items mit dem Wert center verwenden, aber dann füllt der Hintergrund nicht den gesamten Bereich des Elements aus. Der Standardwert für align-items ist stretch – sobald Sie ihn auf einen anderen Wert setzen, füllt er den Raum nicht mehr aus. Lassen Sie ihn stattdessen auf stretch gesetzt und wandeln Sie unser Grid-Element in einen Flex-Container um.

.grid {
  align-items: stretch;
}

.griditem {
  display: flex;
  align-items: center;
}

Die Verwendung negativer Zeilennummern kann sehr hilfreich sein

Stellen Sie sich ein aktuelles CSS Grid Framework mit einem 12-Spalten-Grid vor. Bei kleinen Bildschirmen wird der Inhalt nicht nur durch die Reduzierung der Spaltenanzahl, sondern auch dadurch, dass er sich über alle zwölf Spalten erstreckt, so dargestellt, als wäre er eine einzelne Vollbildspalte.

Sie könnten dasselbe mit Grid tun.

/* For small screens */
.span4, .span6, .spanAll {
  grid-column-end: span 12;
}

/* For large screens */
@media (min-width: 650px) {
  .span4 {
    grid-column-end: span 4;
  }
  .span6 {
    grid-column-end: span 6;
  }
}

An diesem Ansatz ist nichts falsch. Mit CSS Grid ist es jedoch genauso einfach, die Spaltenanzahl neu zu definieren. Durch die Verwendung von -1 können Sie sicherstellen, dass Ihr Inhalt immer bis zum Ende reicht.

/* For small screens */
.span4, .span6, .spanAll {
  grid-column-end: -1;
}

Für einen großen Bildschirm möchten Sie vielleicht zwölf Spalten haben. Für ein Mobiltelefon, irgendwo zwischen einer und vier. Es ist einfach, den Wert von grid-template-columns mit einer Media Query zu ändern.

.grid {
  grid-template-columns: 1fr 1fr;
}

@media (min-width: 700px) {
  .grid {
    grid-template-columns: repeat(12, 1fr);
  }
}

Es gibt wahrscheinlich einige Elemente, die wir für alle Bildschirmgrößen über den gesamten Viewport erstrecken möchten, wie z. B. den Header, den Footer oder einige Hero-Bilder.

Für kleine Bildschirme könnten wir schreiben:

.wide {
  grid-column: 1 / 3; /* start at 1, end at 3 */
}

Sobald wir jedoch unsere Media Query erstellen, werden diese Elemente nur die ersten beiden Spalten von zwölf abdecken. Wir *könnten* den neuen gewünschten Wert für grid-column-end von 13 in dieselbe Media Query aufnehmen, aber es gibt eine weitaus einfachere Methode. Setzen Sie einfach den Endwert auf -1, und er wird sich über *alle* Spalten erstrecken, egal wie viele es gibt. Zum Beispiel:

.wide, .hero, .header, .footer {
  grid-column: 1 / -1;
}

Siehe den Stift Einfachere Media Queries mit -1 von CSS GRID (@cssgrid) auf CodePen.

Grid-Bereiche erstellen implizite Zeilennamen

Benannte Grid-Template-Bereiche und Grid-Liniennummern sind zwei Möglichkeiten, Inhalte im Grid zu platzieren, aber Sie können beide Platzierungsmethoden in demselben Grid verwenden. Sie können auch die impliziten Zeilennamen nutzen, die erstellt werden, wenn Sie einen Grid-Bereich festlegen.

.grid {
  grid-template-areas: "main main sidebar sidebar";
}

Mit diesem Code haben wir gerade vier implizite Zeilennamen erstellt: main-start, main-end, sidebar-start und sidebar-end.

Dies kann nützlich sein, wenn Sie Inhalte entweder über mehrere Grid-Bereiche oder in einem bestimmten Unterabschnitt eines Grid-Bereichs überlappen möchten.

Siehe den Stift Implizite Zeilennamen mit Grid-Bereichen von CSS-Tricks (@css-tricks) auf CodePen.

Es gibt eine zweite Methode zur Definition von Grid-Bereichen

So wie Grid-Bereiche Zeilennamen erstellen, können spezifische Zeilennamen Grid-Bereiche erstellen. Die Syntax zur Definition von Grid-Bereichen sieht wie folgt aus:

.grid {
  grid-template-areas: 
    "header header header"
    "main main sidebar"
    "footer footer footer";
}

Diese Syntax kann etwas umständlich werden, wenn Sie viel freien Platz in Ihrem Design haben (zu viele Punkte! Punkte bedeuten, anstelle eines Namens, eine leere Zelle). Möglicherweise wissen Sie nicht, dass es eine weitere Möglichkeit gibt, Grid-Bereiche zu definieren. Wir können Grid-Linien beliebig benennen. Wenn wir jedoch die Namenskonvention [name-start] und [name-end] befolgen, können wir Grid-Bereiche erstellen. Hier ist ein Beispiel:

.grid {
  display: grid;
  grid-template-columns: 20px 100px [main-start] 1fr [main-end] 100px 20px;
  grid-template-rows: 100px [main-start] 100px [main-end] 100px;
}

.griditem1 {
  background-color: red;
  grid-area: main;
}

Siehe den Stift Eine andere Methode zur Definition von Grid-Bereichen von CSS GRID (@cssgrid) auf CodePen.

Sie würden wahrscheinlich nicht eine ganze Seite mit dieser Methode gestalten, aber wenn Sie grid-area-Platzierung mit liniennummernbasierter Platzierung kombinieren möchten, ist es gut zu wissen.

Verwenden Sie vmin für ein gleichgroßes Box-Layout

CSS Grid ermöglicht die Verwendung jeder beliebigen Maßeinheit für Ihre Zeilen und Spalten. Möchten Sie gleichgroße Boxen, die aber auch responsiv sein sollen? Wenn Sie möchten, dass sich Inhalte mit dem Container ändern, können Sie Viewport-Einheiten verwenden.

.grid {
  grid-template-columns: repeat(5, 20vw);
  grid-template-rows: repeat(5, 20vh);
}

Dies würde auf Desktops und Laptops perfekt funktionieren, aber auf Mobiltelefonen, wo die Höhe des Bildschirms die Breite übersteigt, werden unsere Inhalte überlaufen und eine horizontale Scrollleiste erzeugen. Dudley Storey hat kürzlich einen Blogbeitrag über die Nützlichkeit einer weniger bekannten CSS-Einheit: vmin geschrieben. Diese Einheit ist ein Prozentsatz der Viewport-Breite auf einem Porträtbildschirm und ein Prozentsatz der Viewport-Höhe auf einem Landschaftsbildschirm.

.gridcontainer {
  display: grid;
  width: 100vw;
  height: 100vh;
  justify-content: center;
  align-content: center;
  grid-template-columns: repeat(5, 20vmin);
  grid-template-rows: repeat(5, 20vmin);
}

Wir haben jetzt gleichgroße Boxen, die sich an jede Bildschirmgröße anpassen.

Siehe den Stift Boxy Layout mit CSS Grid und vmin von CSS GRID (@cssgrid) auf CodePen.

Absolute Positionierung

Wenn Sie ein Grid-Element absolut positionieren, wird sein Positionierungskontext nicht mehr sein Container (d. h. das gesamte Grid), sondern wir können es relativ zu seinen angegebenen Grid-Spalten- und Grid-Zeilen-Start- und Endlinien positionieren. Wie üblich entfernt position: absolute ein Element aus dem Dokumentenfluss (d. h. es wird von anderen Elementen ignoriert). Dies macht die absolute Positionierung nützlich, wenn Sie Grid-Elemente überlappen möchten, ohne den automatischen Platzierungsalgorithmus des Grids zu stören. Die automatische Platzierung geht aufwendig darauf ein, Elemente *nicht* zu überlappen, es sei denn, Sie definieren explizit sowohl einen grid-column-start als auch einen grid-row-start Wert für jedes Element.

Versuchen Sie, position: absolute; aus dem Div in diesem Beispiel zu löschen und überlegen Sie, wie viele Elemente Sie für Grid-Spalten- und Grid-Zeilen-Eigenschaften definieren müssten!

Siehe den Stift Automatisches Platzieren mit position: absolute beibehalten von CSS GRID (@cssgrid) auf CodePen.

Order funktioniert anders, als Sie vielleicht denken

Wenn Sie die Flexbox-Eigenschaft order verwendet haben, sind Sie bereits bestens vorbereitet. Alle Grid-Elemente haben einen Standard-Order-Wert von 0. Daher würde order: 1; auf ein Grid-Element angewendet werden, damit es *nach* allem anderen angezeigt wird, nicht *davor*.

Sie können negative Zahlen verwenden, um Elemente nach vorne zu verschieben.

Siehe den Stift Order-Wert von CSS GRID (@cssgrid) auf CodePen.

Die Grenzen von minmax

Möchten Sie Spalten, die den Raum gleichmäßig untereinander aufteilen, bis sie eine maximale Breite erreichen? Sie denken vielleicht, Sie könnten minmax() so verwenden:

.grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(1fr, 300px));
}

Leider wird das nicht funktionieren. Wenn der Maximalwert kleiner ist als der Minimalwert, wird er ignoriert. Das fr ist als Minimalwert in minmax() ungültig. Dieses Verhalten ist jedoch sehr leicht zu erreichen. Das Wort auto, wenn es als Wert in grid-template-columns oder grid-template-rows verwendet wird, macht die Spalte oder Zeile so groß wie ihr Inhalt.

Siehe den Stift Der Wert von auto vs fr von CSS GRID (@cssgrid) auf CodePen.

Dann können wir eine max-width für den Inhalt festlegen.

.grid {
  display: grid;
  grid-template-columns: repeat(3, auto);
}

.item {
  max-width: 300px;
}

Siehe den Stift Die Grenzen von minmax von CSS GRID (@cssgrid) auf CodePen.

Es mag gute Gründe für das Verhalten von minmax() geben und Anwendungsfälle, an die ich noch nicht gedacht habe. Trotzdem habe ich einen ganzen Beitrag auf Medium mit dem Titel Das Einzige, was ich an Grid hasse geschrieben.

Dinge sind viel einfacher, wenn Sie Ihren Grid-Linien Namen geben

Es gibt mehrere Ansätze, die Sie verfolgen können. Wenn Sie sehr tippen möchten, können Sie Linien mehrere Namen geben.

.grid {
  grid-template-columns: [col1-start] 1fr [col1-end col2-start] 1fr [col2-end];
}

Die einfachste Namenskonvention nutzt die automatische Nummerierung des Grids. Wir müssen nicht [col2] tippen, wir können einfach den Namen col gefolgt von einer Zahl eingeben.

.griditem1 {
  grid-column-start: col 2;
}

In Kombination mit dem Schlüsselwort `span` können wir aufhören, über *Liniennummern* nachzudenken und stattdessen über die erste Spalte, die unser Inhalt ausfüllen soll, und die Anzahl der Spalten, die wir beanspruchen möchten, nachdenken, was viel intuitiver ist.

.grid {
  grid-template-columns: repeat(4, [col] 100px);
}

.griditem1 {
  grid-column: col 2 / span 2;
}

Die fr-Einheit macht Rechnen überflüssig

Nehmen wir an, wir möchten unser Grid in vier gleiche Spalten aufteilen. Es ist einfach, die Prozentsätze zu berechnen. Wir schreiben einfach grid-template-columns: 25% 25% 25% 25%.

Was ist, wenn wir dann die grid-gap-Eigenschaft nutzen möchten? grid-gap: 10px. Wir haben drei Lücken zwischen unseren Spalten, daher wird die Breite unseres Grids nun 100% + 30px betragen, und unerwünschte horizontale Scrollbalken erscheinen, wobei ein Teil des Inhalts rechts vom Bildschirm überläuft. Wir könnten `calc` verwenden, um unser Problem zu lösen, aber die Verwendung der `fr`-Einheit ist weitaus einfacher: grid-template-columns: 1fr 1fr 1fr 1fr.

Siehe den Stift fr-Einheit vs. Prozent von CSS GRID (@cssgrid) auf CodePen.

Das Zweite, was ich an Grid hasse

Es gibt keine Möglichkeit, den automatischen Platzierungsalgorithmus zu zwingen, einige Spalten oder Zeilen leer zu lassen.

Die Werte für grid-gap bieten eine einfache Möglichkeit, unseren Inhalt zu verteilen. Während wir einen separaten Wert angeben können, um unsere Spalten und Zeilen mit grid-row-gap und grid-column-gap zu trennen, müssen diese Werte einheitlich sein. Wenn wir unsere erste und zweite Zeile um zehn Pixel und unsere zweite und dritte Zeile um 50 Pixel trennen möchten, bietet uns Grid keine Möglichkeit dafür, außer durch das Erstellen von Zeilen und das Leeren dieser Zeilen.
Sie haben vielleicht die Punkte im grid-template-areas-Syntax gesehen.

grid-template-areas: 
  "header header header"
  "main    main   main"
  "  .       .       ."
  "secondary secondary secondary"
  "footer footer footer";

Dies hätte eine einfache Möglichkeit bieten können, den automatischen Platzierungsalgorithmus zu steuern und ihn daran zu hindern, Elemente in diesen Bereichen zu platzieren. Leider funktioniert das nicht so: Diese Syntax bezeichnet lediglich, dass wir die dritte Zeile nicht in einen benannten Grid-Bereich umwandeln möchten. Automatisch platzierte Elemente *werden* trotzdem dort landen.

Einige Design-Ratschläge: Sie brauchen nicht unbedingt 12 Spalten (und Spalten müssen nicht gleich groß sein)

Zwölf Spalten sind der Standard im Webdesign. Das Bootstrap-Grid verwendet 12 Spalten und fast jedes andere Grid-Framework derzeit. Es gibt einen guten Grund dafür: Zwölf ist durch drei und vier teilbar, was mehr Flexibilität bei der Gestaltung von Inhalten auf der Seite bietet. Wir können unsere Inhalte gleichmäßig in 12 Teile, 6 Teile, 4 Teile, 3 Teile oder in zwei Hälften aufteilen.

Während einige Leute die Vertrautheit mögen, die mit der konsistenten Verwendung desselben Grids für jedes Projekt einhergeht, besteht keine Notwendigkeit, mehr Spalten zu haben, als Sie tatsächlich benötigen, und Sie sollten das Grid erstellen, das für Ihren Inhalt und das gewünschte Layout richtig ist, anstatt einer Einheitslösung.

Schauen Sie sich die Beispiele auf Gridset an. Gridset ist ein nützliches Werkzeug zur Erstellung von Grids, aber sobald das native CSS Grid-Modul verfügbar ist, werden Sie Werkzeuge wie dieses nicht mehr benötigen. Es zeigt einige exzellent gestaltete Grids.

Ich habe mir erlaubt, eines davon mit den CSS Grids nachzubauen.

Siehe den Stift Textlayout mit CSS Grid-Modul von CSS GRID (@cssgrid) auf CodePen.