防止内容扩展网格项目


153

TL; DR:table-layout: fixed CSS网格有什么类似的东西吗?


我试图用几个月的大4x3网格创建年视图日历,而白天则嵌套7x6网格。

日历应填满页面,因此Year网格容器的宽度和高度分别为100%。

.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);
}

这是一个工作示例:https : //codepen.io/loilo/full/ryXLpO/

为简单起见,该笔中的每个月都有31天,从星期一开始。

我还选择了一个可笑的小字体来演示该问题:

网格项(=日单元格)非常简洁,因为页面上有数百个。当日期数字标签过大(可以使用左上角的按钮随意使用笔中的字体大小)时,网格的大小就会增大,并超过页面的主体尺寸。

有什么办法可以防止这种行为?

我最初宣布年份网格的宽度和高度为100%,所以这可能是起点,但是我找不到任何与网格相关的CSS属性都可以满足这一需求。

免责声明:我知道有很简单的方法可以设置日历的样式,而无需使用CSS网格布局。但是,这个问题更多地是关于该主题的常识而不是解决具体示例。


您想做什么呢?每个单元格中的字体可以是任意大小,而不会导致网格单元格大小增加吗?
Michael Coker

1
究竟。基本上,如果我将网格项目的大小设置为根据百分比值而不是分数,则将是一种更方便的方式。
Loilo

我基本上是在寻找表格布局的网格布局版本:固定(请参阅:codepen.io/loilo/pen/dvxpvq?editors=1100
Loilo

7
这是整个CSS Grid规范中最大的麻烦。他们的需求是网格区域不能逃脱其任何父网格容器的尺寸的设置!照原样,这是深层嵌套网格结构的噩梦。
Lonnie Best

Answers:


263

默认情况下,网格项目不能小于其内容的大小。

网格项目的初始大小为min-width: automin-height: auto

你可以通过设置网格项目覆盖这种行为min-width: 0min-height: 0overflow比其它任何值visible

从规格:

6.6。网格项目的自动最小大小

为网格项目,该规范定义了提供更合理的默认最小大小auto的值min-width/ min-height在指定的轴的自动最小尺寸也适用于它的网格项目overflowvisible。(效果类似于对弹性物品施加的自动最小尺寸。)

这是有关弹性项目的更详细说明,但它也适用于网格项目:

这篇文章还介绍了嵌套容器的潜在问题以及主要浏览器之间已知的呈现差异


要修复您的布局,请对您的代码进行以下调整:

.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 */
}

修改后的代码笔


1frminmax(0, 1fr)

上面的解决方案在网格项目级别上运行。有关容器级别的解决方案,请参阅以下文章:


3
哇。这既有趣又有趣,而我绝对不会仅仅通过尝试来解决这个问题。您是否只是在规格说明中浏览了该信息?因为在不知道要为Google做什么之后,这就是我之前尝试过的方法,但是我最终读错了部分(得出问题的错误原因之后)。
Loilo

1
在使用flex项目之前,我曾遇到过这个问题。由于flex和grid项之间有许多相似之处,我认为其行为可能是相同的,并且在规范的该部分中归零。
Michael Benjamin

1
它可以固定高度,但是会继续在水平方向上增长,min-width: 0;这无济于事。我想念什么吗?
用户

2
对于嵌套网格,我们需要将其应用于所有级别。但是我真的是来这里投票并谢谢你的。–纳克
Knack)


57

以前的答案是相当不错的,但我也想提一提,有有固定的布局相当于为网格,你只需要编写minmax(0, 1fr),而不是1fr为你的轨道的大小。


6
我建议在以前接受的答案之前使用这种方法。
蒂埃里·普罗斯特

尽管这行得通,但我一点也不明白。您能否解释一下为什么行得通?minmax(0,1fr)在做什么?那不应该总是0吗?我很困惑:(
BAERUS

2
minmax(0, 1fr)之所以有效,1fr是因为它实际上是的简写minmax(auto,1fr),而不是原始问题的正确值。
Mikko Rantalainen

有关更多详细信息,请参见github.com/w3c/csswg-drafts/issues/1777
Mikko Rantalainen

1

现有的答案可以解决大多数情况。但是,我遇到了需要将grid-cell的内容设置为的情况overflow: visible。我通过绝对定位在包装器中来解决此问题(不是理想的,但是我所知道的最好的),如下所示:


.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


0

一个更容易的事情是像这样设置网格项的最大宽度:

//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
  }

老实说,我有点困惑。您的代码根本不类似于原始问题,并且将max-width:100%应用于网格项(而不是接受的解决方案中的min-width:0)将无法解决问题...
Loilo

max-width会阻止其相对于其子宽度进行重新调整
Pedro JR

我试图重现您的代码,并且它确实有效,但是似乎不是由于max-width:100%而是因为grid-column:span 4; 而不定义起始列。定义起始列(例如,使用grid-column:1 / span 4;),它将再次中断布局。(这种行为有点怪异,但是我确定规范中的某个地方定义了这个角落。)
Loilo

好吧,听起来不错。但您尚未考虑我的支持
Pedro JR

坦率地说:1.这已经解决了三年多了。2.您的答案没有经过正确测试(您的CSS包含多种错别字,在浏览器甚至无法识别您的网格之前,都需要对其进行修复)。3.您的答案实际上并没有满足我问题中的示例(否则,您将意识到您的解决方案不适用于该示例)。—所以,不,对不起,但我没有考虑投票。
Loilo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.