Verhindern Sie, dass Inhalte Rasterelemente erweitern

153

TL; DR: Gibt es etwas Ähnliches table-layout: fixedfür CSS-Grids?


Ich habe versucht, einen Jahresansichtskalender mit einem großen 4x3-Raster für die Monate und darin verschachtelten 7x6-Raster für die Tage zu erstellen.

Der Kalender sollte die Seite füllen, damit der Jahresrastercontainer eine Breite und Höhe von jeweils 100% erhält.

.year-grid {
  width: 100%;
  height: 100%;

  display: grid;
  grid-template: repeat(3, 1fr) / repeat(4, 1fr);
}

.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
}

Hier ist ein funktionierendes Beispiel: https://codepen.io/loilo/full/ryXLpO/

Der Einfachheit halber hat jeder Monat in diesem Stift 31 Tage und beginnt an einem Montag.

Ich habe auch eine lächerlich kleine Schriftgröße gewählt, um das Problem zu demonstrieren:

Rasterelemente (= Tageszellen) sind ziemlich komprimiert, da sich mehrere Hundert davon auf der Seite befinden. Und sobald die Beschriftungen der Tagesnummern zu groß werden (spielen Sie mit den Schaltflächen oben links mit der Schriftgröße im Stift), wird das Raster nur größer und überschreitet die Körpergröße der Seite.

Gibt es eine Möglichkeit, dieses Verhalten zu verhindern?

Ich habe mein Jahresraster anfangs als 100% breit und hoch deklariert, daher ist dies wahrscheinlich der Ausgangspunkt, aber ich konnte keine gitterbezogenen CSS-Eigenschaften finden, die diesen Anforderungen entsprochen hätten.

Haftungsausschluss: Mir ist bewusst, dass es ziemlich einfache Möglichkeiten gibt, diesen Kalender ohne Verwendung des CSS-Rasterlayouts zu gestalten. Bei dieser Frage geht es jedoch mehr um das Allgemeinwissen zum Thema als um die Lösung des konkreten Beispiels.

Loilo
quelle
Was willst du stattdessen passieren? Die Schriftart in jeder Zelle kann einfach eine beliebige Größe haben und führt nie dazu, dass die Größe der Rasterzellen zunimmt.
Michael Coker
1
Genau. Grundsätzlich eine bequemere Möglichkeit, was passieren würde, wenn ich die Größe der Rasterelemente auf entsprechende Prozentwerte anstelle von Brüchen einstelle.
Loilo
Ich bin im Grunde auf der Suche nach einer Grid-Layout-Version des Tabellen-Layouts: behoben (siehe: codepen.io/loilo/pen/dvxpvq?editors=1100 )
Loilo
7
Dies ist der größte Schmerz in der gesamten CSS-Grid-Spezifikation. Sie müssen eine Umgebung sein, in der Gitterbereiche nicht den Abmessungen eines ihrer übergeordneten Gittercontainer entkommen können! So wie es ist, ist es ein Albtraum für tief verschachtelte Gitterstrukturen.
Lonnie Best

Antworten:

262

Standardmäßig darf ein Rasterelement nicht kleiner als der Inhalt sein.

Rasterelemente haben eine Anfangsgröße von min-width: autound min-height: auto.

Sie können dieses Verhalten außer Kraft setzen , indem Rasterelemente Einstellung min-width: 0, min-height: 0oder overflowmit einem anderen Wert als visible.

Aus der Spezifikation:

6.6. Automatische Mindestgröße der Rasterelemente

Um eine vernünftigere Standard-Mindestgröße für Rasterelemente bereitzustellen, definiert diese Spezifikation, dass der autoWert von min-width/ min-heightauch eine automatische Mindestgröße in der angegebenen Achse auf Rasterelemente anwendet, deren Größe overflowist visible. (Der Effekt ist analog zu der automatischen Mindestgröße für Flex-Artikel.)

Hier ist eine detailliertere Erklärung zu Flex-Elementen, die jedoch auch für Rasterelemente gilt:

Dieser Beitrag behandelt auch potenzielle Probleme mit verschachtelten Containern und bekannte Rendering-Unterschiede zwischen den wichtigsten Browsern .


Nehmen Sie die folgenden Anpassungen an Ihrem Code vor, um Ihr Layout zu korrigieren:

.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
  background: #fff;
  grid-gap: 2px;
  min-height: 0;  /* NEW */
  min-width: 0;   /* NEW; needed for Firefox */
}

.day-item {
  padding: 10px;
  background: #DFE7E7;
  overflow: hidden;  /* NEW */
  min-width: 0;      /* NEW; needed for Firefox */
}

überarbeiteter Codepen


1fr vs. minmax(0, 1fr)

Die obige Lösung wird auf der Ebene der Rasterelemente ausgeführt. Eine Lösung auf Containerebene finden Sie in diesem Beitrag:

Michael Benjamin
quelle
3
Beeindruckend. Das ist faszinierend und interessant zugleich, und ich hätte mir das definitiv nicht ausgedacht, wenn ich es nur ausprobiert hätte. Haben Sie gerade einen Blick in die Spezifikation für diese Informationen geworfen? Denn nachdem ich nicht wusste, wofür ich googeln soll, habe ich es zuvor versucht, aber am Ende habe ich den falschen Abschnitt gelesen (nachdem ich die falsche Ursache des Problems festgestellt hatte).
Loilo
1
Ich war zuvor mit Flex-Artikeln auf dieses Problem gestoßen . Da es viele Ähnlichkeiten zwischen Flex- und Grid-Elementen gibt, nahm ich an, dass das Verhalten möglicherweise dasselbe ist, und konzentrierte mich auf diesen Abschnitt der Spezifikation.
Michael Benjamin
1
Es fixiert die Höhe, aber es wächst weiter in horizontaler Richtung, min-width: 0;hilft nicht. Vermisse ich etwas
Benutzer
2
Für verschachtelte Gitter müssen wir dies auf alle Ebenen anwenden. Aber ich bin wirklich hierher gekommen, um zu stimmen und danke.
Knack
2
@PragyAgarwal .. stackoverflow.com/users/3597276/michael-b?tab=answers :-)
Michael Benjamin
57

Die vorherige Antwort ist ziemlich gut, aber ich wollte auch erwähnen , dass es ist ein festes Layout äquivalent für Netze, müssen Sie nur schreiben , minmax(0, 1fr)anstatt 1frals Track - Größe.

FremyCompany
quelle
6
Ich empfehle diesen Ansatz gegenüber der vorherigen, akzeptierten Antwort.
Thierry Prost
Obwohl dies funktioniert, verstehe ich ein bisschen davon nicht ... Können Sie vielleicht erklären, warum dies funktioniert? Was macht minmax (0, 1fr)? Sollte das nicht immer 0 sein? Ich bin verwirrt :(
BAERUS
2
minmax(0, 1fr)funktioniert, weil 1fres wirklich eine Abkürzung für ist minmax(auto,1fr), was nicht der richtige Wert für die ursprüngliche Frage ist.
Mikko Rantalainen
Weitere Informationen finden Sie unter github.com/w3c/csswg-drafts/issues/1777
Mikko Rantalainen
1

Die vorhandenen Antworten lösen die meisten Fälle. Ich stieß jedoch auf einen Fall, in dem der Inhalt der Gitterzelle benötigt wurde overflow: visible. Ich habe es gelöst, indem ich es absolut in einem Wrapper positioniert habe (nicht ideal, aber das Beste, was ich weiß), wie folgt:


.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
  background: #fff;
  grid-gap: 2px;  
}

.day-item-wrapper {
  position: relative;
}

.day-item {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px;

  background: rgba(0,0,0,0.1);
}

https://codepen.io/bjnsn/pen/vYYVPZv

bjnsn
quelle
0

Eine einfachere Möglichkeit besteht darin, die maximale Breite des Rasterelements wie folgt festzulegen:

//for the container
.gridContainer{
    display: grid;
    grids-templates-column: repeat (12, 1fr);
 }

 //for the grid item
 .gridItem{
       max-width: 100%;
       grid-column: span 4  //4 can be any number from1-12 as we specified in the grid template
  }
Pedro JR
quelle
Ich bin ein bisschen verwirrt, um ehrlich zu sein. Ihr Code ähnelt überhaupt nicht der ursprünglichen Frage, und das Anwenden von max-width: 100% auf die Rasterelemente (anstelle von min-width: 0 aus der akzeptierten Lösung) löst das Problem nicht ...
Loilo
Die maximale Breite verhindert, dass sie sich relativ zur untergeordneten Breite neu anpasst
Pedro JR
Ich habe versucht, Ihren Code zu reproduzieren, und es funktioniert tatsächlich, aber es scheint nicht an der maximalen Breite zu liegen: 100%, sondern an der Rasterspalte: span 4; ohne eine Startspalte zu definieren. Definieren Sie eine Startspalte (z. B. mithilfe der Rasterspalte: 1 / span 4;), und das Layout wird erneut unterbrochen. (Dieses Verhalten ist etwas seltsam, aber ich bin sicher, dass es irgendwo in der Spezifikation eine Ecke gibt, in der dies definiert ist.)
Loilo
Okay klingt gut. Aber Sie erwägen noch keine Gegenstimme für mich
Pedro JR
Um ehrlich zu sein: 1. Dies ist seit über drei Jahren ein gelöstes Problem. 2. Ihre Antwort wurde nicht richtig getestet (Ihr CSS enthält mehrere Tippfehler, die behoben werden müssen, bevor der Browser Ihr Raster überhaupt erkennt). Und 3. Ihre Antwort entsprach nicht dem Beispiel in meiner Frage (sonst hätten Sie festgestellt, dass Ihre Lösung damit nicht funktioniert). - Also nein, es tut mir leid, aber ich denke nicht über eine Gegenstimme nach.
Loilo