有什么像表格布局:修复CSS网格吗?


我尝试创建一个年视图日历,用一个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: auto和min-height: auto。

您可以通过将网格项设置为min-width: 0、min-height: 0或溢出除可见值以外的任何值来覆盖此行为。

来自规范:

6.6. 自动最小网格大小 项目 为网格项提供更合理的默认最小大小,这 规范定义了min-width / min-height的自动值还将指定轴上的自动最小大小应用于溢出可见的网格项。(效果类似于自动施加在伸缩物品上的最小尺寸。)

下面是一个关于flex项目的更详细的解释,但它也适用于网格项目:

为什么伸缩项目不能缩小过去的内容大小?

这篇文章还涵盖了嵌套容器的潜在问题和主要浏览器之间已知的呈现差异。


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

.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演示


1fr vs minmax(0,1fr)

上面的解决方案在网格项级别上操作。对于容器级的解决方案,请参阅这篇文章:

谁用最小最大值(0,1fr)来处理长元素,而1fr不行?


之前的答案很好,但我也想提到网格有一个固定的布局等效,你只需要写minmax(0,1fr)而不是1fr作为你的轨道大小。


现有的答案解决了大多数情况。然而,我遇到了需要网格单元格的内容溢出的情况:可见。我通过绝对定位在包装器中解决了这个问题(不是最理想的,但我知道最好的),就像这样:


.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