【问题标题】:Prevent content from expanding grid items防止内容扩展网格项
【发布时间】:2017-09-04 20:01:57
【问题描述】:

TL;DR: 有没有类似 table-layout: fixed 的 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 网格布局的情况下设置日历样式。但是,这个问题更多的是关于该主题的一般知识,而不是解决具体示例。

【问题讨论】:

  • 你想做什么?每个单元格中的字体可以是任意大小,并且不会导致网格单元格大小增加?
  • 没错。如果我将网格项的大小设置为根据百分比值而不是分数,基本上是一种更方便的方法。
  • 我基本上是在寻找表格布局的网格布局版本:固定(参见:codepen.io/loilo/pen/dvxpvq?editors=1100
  • 这是整个 CSS Grid 规范中最大的痛点。他们需要一个网格区域无法逃脱其任何父网格容器尺寸的设置!事实上,对于深度嵌套的网格结构来说,这是一场噩梦。

标签: css grid-layout css-grid


【解决方案1】:

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

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

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

来自规范:

6.6. Automatic Minimum Size of Grid Items

为了给网格项提供一个更合理的默认最小尺寸,这个 规范定义了min-width/min-heightauto 值还将指定轴上的自动最小尺寸应用于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 */
}

jsFiddle demo


1frminmax(0, 1fr)

上述解决方案在网格项级别运行。有关容器级别的解决方案,请参阅这篇文章:

【讨论】:

  • 哇。这既迷人又有趣,我绝对不会只是尝试一下就想出这个。您是否只是浏览了该信息的规范?因为在不知道用谷歌搜索什么之后,这就是我之前尝试过的,但我最终阅读了错误的部分(在得出问题的错误原因之后)。
  • 它固定了高度,但它在水平方向上继续增长,min-width: 0; 没有帮助。我错过了什么吗?
  • @user,网格布局实现在 Chrome 和 Firefox 之间明显不同。我的答案中的原始代码适用于 Chrome。但它需要进一步调整才能在 FF 中工作。将min-width: 0 添加到.month-grid.day-item。答案已修改。
  • 对于嵌套网格,我们需要将其应用于所有级别。但我真的来这里是为了支持和感谢你..
  • css 规范贡献者应该停止吸毒。为什么不用新关键字?为什么要对已经存在的属性做出甚至没有意义的特殊行为? ... css 会变得简单直观吗?
【解决方案2】:

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

【讨论】:

  • 我推荐这种方法而不是以前接受的答案。
  • 虽然这行得通,但我有点不明白......你能解释一下为什么会这样吗? minmax(0, 1fr) 在做什么?那不应该总是0吗?我很困惑:(
  • minmax(0, 1fr) 有效,因为1fr 实际上是minmax(auto,1fr) 的简写,这不是原始问题的正确值。
  • 所有其他答案都是黑客,这应该是公认的答案
【解决方案3】:

现有的答案可以解决大多数情况。但是,我遇到了需要网格单元的内容为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

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多