防止内容扩展网格项

Prevent content from expanding grid items

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


我尝试创建一个年视图日历,月份为 4x3 大网格,日期为 7x6 嵌套网格。

日历应填满页面,因此年网格容器的宽度和高度各为 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 网格布局的情况下设置日历的样式。但是,这道题更多的是关于该主题的一般知识,而不是解决具体的例子。

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

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

您可以通过将网格项设置为 min-width: 0min-height: 0overflow 以及 visible 以外的任何值来覆盖此行为。

来自规范:

6.6. Automatic Minimum Size of Grid Items

To provide a more reasonable default minimum size for grid items, this specification defines that the auto value of min-width / min-height also applies an automatic minimum size in the specified axis to grid items whose overflow is visible. (The effect is analogous to the automatic minimum size imposed on flex items.)

这里有一个关于弹性项目的更详细的解释,但它也适用于网格项目:

此 post 还涵盖了 嵌套容器 的潜在问题和已知的 主要浏览器之间的渲染差异 .


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

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

jsFiddle demo


1fr 对比 minmax(0, 1fr)

上面的解决方案在网格项目级别运行。对于容器级别的解决方案,请参阅此 post:

前面的回答很好,但我也想提一下 固定的网格布局等价物,你只需要写 minmax(0, 1fr) 而不是1fr 作为您的曲目大小。

现有答案解决了大多数情况。然而,我 运行 进入了一个案例,我需要网格单元格的内容是 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