Graben in die Display-Eigenschaft: Grids ganz unten

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Als Fortsetzung einer Serie über die display -Eigenschaft in CSS wirft Rachel Andrew dieses Mal einen Blick darauf, was passiert, wenn Sie grid als Anzeigewert verwenden, mit zusätzlichen Informationen darüber, wie subgrid dieses Verhalten ändert.

Heute werden wir uns ansehen, was passiert, wenn wir display: grid verwenden und wie wir den neuen Subgrid-Wert von grid-template-columns und grid-template-rows rows verwenden könnten, um Grids bis ganz nach unten durch unser Markup zu ermöglichen , die sich aufeinander beziehen.

Dieser Artikel ist Teil einer Reihe, die sich mit verschiedenen Aspekten der CSS- display befasst, und ist eine Fortsetzung der ersten beiden Artikel:

  1. Die zwei display
  2. Box-Generation
  3. Gitter ganz nach unten

Was passiert, wenn wir einen Grid-Container erstellen?

CSS Grid Layout wird mit display: grid eingeschaltet. Wenn Sie den ersten Artikel dieser Reihe gelesen haben, wissen Sie, dass diese Einzelwert-Eigenschaft eigentlich display: block grid bedeutet. Wir erhalten eine Box auf Blockebene, die als Grid-Container definiert ist, mit direkten untergeordneten Elementen, die Grid-Elemente sind und am Grid-Layout teilnehmen.

Wenn Sie sich die Display-Spezifikation ansehen, sehen Sie das in der Tabelle, die all die verschiedenen Werte für display definiert. Die Wörter Grid-Container sind mit der Definition eines Grid-Containers in der Grid-Spezifikation verknüpft. Um herauszufinden, was das eigentlich bedeutet, müssen wir also dort nachsehen. Wenn wir das tun, erhalten wir einige nützliche Erläuterungen zum Verhalten eines Grid-Containers.

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Ein Grid-Container soll einen Grid-Formatierungskontext aufbauen, der einem Block-Formatierungskontext (BFC) ähnlich ist. Ich habe eine ausführliche Anleitung zum Blockformatierungskontext geschrieben. In diesem Artikel werden Sie zwei Dinge über einen BFC entdecken, die für einen Rasterformatierungskontext gleich sind. Schwimmer dringen nicht in den Gitterbehälter ein, und die Ränder des Behälters fallen nicht mit denen des Inhalts zusammen.

Unterschiede gibt es allerdings erst, wenn wir in den Grid-Container kommen. Die Kinder eines Grid-Containers, die nicht am Block- und Inline-Layout teilnehmen, sind Grid-Elemente und nehmen daher am Grid-Layout teil. Dies bedeutet, dass einige Dinge, die wir von Block- und Inline-Layouts gewohnt sind, nicht zutreffen.

Wenn ein Element im Layout schwebend oder gelöscht ist, haben die Eigenschaften float und clear keine Wirkung, sobald das Element zu einem Rasterelement wird. Die Eigenschaft vertical-align hat keine Auswirkung, und die ::first-letter und ::first-line können nicht verwendet werden.

Die Tatsache, dass ein Element nicht sowohl schwebend als auch ein Rasterelement sein kann, ist hilfreich bei der Erstellung von Fallbacks. Beim Erstellen eines Fallbacks für Browser, die kein Grid mit Floats unterstützen (wenn Grid unterstützt wird), müssen Sie nichts Besonderes tun: Das Float wird überschrieben.

Ich skizziere diesen Ansatz in meinem Artikel zur Unterstützung von Browsern ohne Grid. Es gibt Situationen, in denen sich das Verhalten als problematisch herausgestellt hat, obwohl diese Probleme gelöst werden könnten, indem ein anderer Teil von CSS verwendet wird, wie in diesem Beitrag zum Entpacken eines Problems mit Rastern und Gleitkommazahlen, „Editorial Layouts, Exclusions, and CSS Grid“, beschrieben.

Wenn wir nichts anderes tun, als den Wert von display auf grid zu ändern, werden wir keinen großen Unterschied zu unserem Layout feststellen. Die direkten untergeordneten Elemente sind Rasterelemente, standardmäßig erhalten wir jedoch ein einspaltiges Raster. Ein Raster hat immer eine Spalte und eine Zeile. Der Rest der Zeilen, die wir danach sehen können, sind implizite Zeilen, dh Zeilen, die erstellt wurden, um den Inhalt aufzunehmen.

Ein Kartensatz, der in einer einzigen Spalte untereinander angeordnet ist.
Wenn wir einen Rastercontainer ohne Spalten erstellen, erhalten wir ein einspaltiges Raster. (Große Vorschau)

Wir können anfangen, etwas zu bilden, das für uns eher wie ein Raster aussieht, indem wir der Eigenschaft grid-template-columns einen Wert zuweisen. Die Eigenschaft akzeptiert eine Titelliste als Wert; Wenn ich ihm drei 1fr-Spuren gebe, finden wir uns jetzt in einem dreispaltigen Raster wieder, und die Verwendung der gap -Eigenschaft gibt mir den Abstand zwischen diesen Karten.

Wir haben jetzt etwas, das für uns wie ein Gitter aussieht:

Karten in drei Spalten und zwei Reihen ausgelegt
Wir definieren einige Spaltenspuren und eine Lücke, um ein offensichtliches Rasterlayout zu erhalten (große Vorschau)

Jedes der Rasterelemente in unserem Beispiel hat seine eigenen untergeordneten Elemente. Die Karten haben Kopf- und Fußzeilen und einen Bereich für den Hauptinhalt der Karte. Diese untergeordneten Elemente sind Rasterelemente, aber ihre untergeordneten Elemente sind zum Block- und Inline-Layout zurückgekehrt. Die Kopfzeile, der Inhaltsbereich und die Fußzeile machen keine Raster wie Dinge. Dies liegt daran, dass, wenn wir den Wert von display in grid ändern, es nicht erbt, sondern nur die untergeordneten Elemente zu Grid-Elementen werden; Ihre Kinder kehren zum Blocklayout zurück.

Gitter verschachteln

Wenn eine Karte mehr Inhalt hat als die anderen Karten, werden die Karten in dieser Reihe größer. Der Anfangswert von align-items für Grid-Items ist stretch . Unsere Karten strecken sich bis zur vollen Höhe. Die Gegenstände darin befinden sich jedoch im normalen Block- und Inline-Fluss und dehnen sich daher nicht magisch aus, um die Karte zu füllen. (Deshalb sehen Sie im Bild oben, dass die Karten mit weniger Inhalt unten eine Lücke haben.)

Wenn wir wollten (damit diese Fußzeile immer unten sitzt), könnten wir unser Rasterelement auch zu einem Raster machen. In diesem Fall ist ein einspaltiges Raster alles, was wir brauchen. Wir können dann Zeilenspuren definieren und dem Bereich, in dem sich das div mit einer Inhaltsklasse befindet, eine Spurgröße von 1fr . Dadurch wird der gesamte verfügbare Platz im Container belegt und die Fußzeile an den unteren Rand der Karte verschoben.

Siehe den Stift [Anzeige: Subgrid ist nicht das, was wir wollen] (https://codepen.io/rachelandrew/pen/PvQzeG) von Rachel Andrew.

Siehe Pen Display: Subgrid is not what we want von Rachel Andrew.

Sie können diese Verschachtelung von Rastern so oft durchführen, wie Sie möchten. Ich betrachte es nicht wirklich als Verschachtelung, da wir hier keine verschachtelten Tabellen erstellen und normalerweise die bereits vorhandenen strukturellen HTML-Elemente verwenden. Wir ändern den Wert von display nur stufenweise auf das, was für die untergeordneten Elemente dieses Elements am besten geeignet ist. Das kann Flex-Layout oder Grid-Layout sein, aber meistens wird es Block- und Inline-Layout sein. In diesem Fall müssen wir nichts tun, da dies standardmäßig geschieht.

Ausrichten der Kopf- und Fußzeilen

Wie wir jetzt gesehen haben, benötigen wir sehr wenig CSS, wenn wir einen Kartensatz in einem Raster anzeigen möchten und möchten, dass sie so hoch wie die höchste Karte angezeigt werden, und wir möchten, dass die Fußzeilen an den unteren Rand der Karte verschoben werden . Das Layout-CSS für das obige Beispiel lautet wie folgt:

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; } article { display: grid; grid-template-rows: auto 1fr auto; row-gap: 20px; }

Was aber, wenn die Hintergrundfarbe der Kopf- und Fußzeilen übereinstimmen soll? Jede Karte ist ein Rasterelement, aber die Kopf- und Fußzeilen befinden sich im Raster des Elements. Sie haben keine Beziehung zueinander und deshalb können wir sie nicht in eine Reihe bringen. Hier wäre es schön, wenn wir das Raster irgendwie durch die Kinder vererben könnten.

Wenn wir auf dem übergeordneten Element ein Raster mit drei Zeilen definieren könnten, platzieren Sie die Karten über diese drei Zeilen und lassen Sie Kopf-, Inhalts- und Fußzeile jeweils in einer der Zeilen sitzen. Auf diese Weise würde jeder Header in der gleichen Reihe sein, und wenn ein Header größer würde, würde die ganze Reihe größer werden.

Wir haben heute keine gute Lösung dafür in Browsern, aber sie ist auf dem Weg. Die Subgrid-Funktion von CSS Grid Layout Level 2 ermöglicht genau dieses Muster. Sie können ein Raster auf dem übergeordneten Element erstellen und dann selektiv die Zeilen und/oder Spalten auswählen, um dieses Raster zu verwenden, anstatt ein neues Raster auf dem child Element zu definieren, das völlig unabhängig von diesem Raster ist.

Beachten Sie, dass die folgenden Beispiele zum Zeitpunkt des Schreibens nur in Firefox Nightly funktionieren. Der Subgrid-Wert von grid-template-columns und grid-template-rows ist ein neues Feature und Teil von Level 2 der CSS-Grid-Spezifikation. Um diese Funktion auszuprobieren, laden Sie eine Kopie von Firefox Nightly herunter.

Wie das funktioniert, sehen Sie in den Bildern unten. Im ersten Bild habe ich drei Zeilenspuren auf dem übergeordneten Element erstellt und die Karte darüber gespannt. Wenn der Firefox-Grid-Inspektor das Gitter hervorhebt, können Sie sehen, dass die Zeilen des übergeordneten Elements sich nicht auf die von den untergeordneten Elementen verwendeten Zeilen beziehen.

Ein Bild eines dreispaltigen Rasters mit überlagerten Spuren des Firefox Grid Inspector.
Die Untersuchung des Rasters mit dem Firefox Grid Inspector zeigt, dass die Elemente nicht in den Spuren des übergeordneten Elements angezeigt werden. (Große Vorschau)

Wenn ich, anstatt drei Zeilen auf dem untergeordneten Element zu definieren, den Subgrid-Wert für grid-template-rows verwende, verwendet die Karte jetzt diese Zeilen auf dem übergeordneten Element. Sie können sehen, wie die beiden jetzt ausgerichtet sind und daher auch die Kopf- und Fußzeilen ausgerichtet sind:

Ein Bild eines dreispaltigen Rasters, alle Elemente innerhalb der Karten ausgerichtet.
Mit Subgrid geht jeder Teil der Karte in seine eigene Spur (große Vorschau)

Was wir hier mit subgrid machen, ist kein neuer Wert von display . Das Element, das ein Subgrid ist, ist selbst ein Grid-Container, da wir display: grid darauf eingestellt haben. Die Grid-Items verhalten sich wie normale Grid-Items. Dies ist ein reguläres Rasterlayout – nicht anders als das ursprüngliche verschachtelte Raster, außer dass es (anstatt dass das Element seine eigene Zeilenspurgröße hat) die Spuren des übergeordneten Elements verwendet.

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: repeat(2,auto 1fr auto); } article { grid-row-end: span 3; display: grid; grid-template-rows: subgrid; }

Das ist das Schöne an Subgrids; Es gibt nicht viel zu lernen, wenn Sie bereits wissen, wie man das Rasterlayout verwendet. Die restlichen Details können Sie in meinem vorherigen Beitrag hier im Smashing Magazine „CSS Grid Level 2: Here Comes Subgrid“ nachlesen.

Gestern (23. Mai 2019) ist subgrid in Firefox Nightly gelandet, sodass wir eine testbare Implementierung des subgrid-Werts von grid-template-columns und grid-template-rows haben. Bitte schnappen Sie sich eine Kopie von Nightly und probieren Sie es aus. Mit einer Kopie von Nightly können Sie das letzte Beispiel sehen, das in diesem CodePen funktioniert:

Siehe Pen Display: Subgrid is not what we want von Rachel Andrew.

Siehe Pen Display: Subgrid is not what we want von Rachel Andrew.

Sehen Sie, ob Ihnen andere Anwendungsfälle einfallen, die durch die Subgrid-Funktion gelöst werden, oder vielleicht Dinge, die Ihrer Meinung nach fehlen. Während eine Funktion nur in einem Nightly-Browser verfügbar ist, ist es zu diesem Zeitpunkt möglich, Änderungen an der Spezifikation vorzunehmen, wenn ein Problem entdeckt wird. Tun Sie also Ihrem zukünftigen Webentwicklungsselbst einen Gefallen und probieren Sie Funktionen wie diese aus, damit Sie zur Webplattform beitragen und die Dinge verbessern können.

Wenn Sie der Meinung sind, dass Sie einen Fehler in der Firefox-Implementierung gefunden haben, können Sie sich den Hauptimplementierungsfehler auf Bugzilla ansehen, der auf verwandte Probleme im Abschnitt „ Abhängig von “ verweist. Wenn Sie Ihr Problem nicht sehen können, erstellen Sie einen möglichst einfachen Testfall und melden Sie den Fehler. Wenn Sie der Meinung sind, dass Subgrid etwas tun sollte, um einen Anwendungsfall zu lösen, und dies nicht in der Spezifikation aufgeführt ist, können Sie ein Problem bei der CSS-Arbeitsgruppe GitHub für eine mögliche Verbesserung melden.

Was display: contents ?

Wenn Sie mitverfolgt haben, denken Sie vielleicht, dass display: contents (wie im vorherigen Artikel über display beschrieben) die Probleme lösen könnte, die subgrid zu lösen versucht – nämlich das Zulassen, dass indirekte Kinder an einem Grid-Layout teilnehmen können. Das ist nicht der Fall, und unser Kartenbeispiel ist eine perfekte Möglichkeit, den Unterschied zu demonstrieren.

Wenn wir, anstatt unsere Karte mit display: grid zu einem Rasterlayout zu machen, die Box mit display: contents content entfernen würden, würden wir dieses Ergebnis in diesem nächsten CodePen erhalten. (Versuchen Sie, die display: contents aus den Regeln für .card zu entfernen, um den Unterschied zu sehen.)

Siehe Pen Display: Subgrid is not what we want von Rachel Andrew.

Siehe Pen Display: Subgrid is not what we want von Rachel Andrew.

In diesem Beispiel wurde das Kästchen der Karte entfernt, sodass Kopf-, Inhalts- und Fußzeile direkt am Rasterlayout beteiligt sind und automatisch über das Raster platziert werden. Das wollten wir überhaupt nicht! Der contents der Anzeige wird wirklich hilfreich sein, sobald die in meinem letzten Artikel erwähnten Zugänglichkeitsprobleme in Browsern behandelt wurden, aber er löst andere Probleme als das, das wir untersuchen.

Mehr Lektüre und Beispiele

Ich habe eine Reihe von Beispielen und Demos erstellt, um jedem zu helfen, Subgrids zu verstehen. Sie können diese unter den folgenden Links ausprobieren:

  • CSS Grid Level 2 Beispiele
  • CSS Grid Level 2: Hier kommt das Subgrid
  • Gitter ganz nach unten (Präsentation)
  • MDN-Dokumentation für Subgrid