防止网格溢出

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

假设您有一个非常简单的 CSS 网格布局,其中一列固定为 300px,另一列占用剩余空间,为 1fr

.grid {
  display: grid;
  grid-template-columns: 1fr 300px;
}

这在某种程度上是稳健的。该 1fr 列将占用固定 300px 列留下的任何剩余空间。确实,auto 值也会这样做,但 auto 不太稳健,因为它的尺寸基于内部内容。因此,如果您内容太少,则您的列可能无法填充您想要的整个空间。但是,虽然 1fr 略微更稳健,但它并不能完全保护您免受内容过大的影响!

以下是网格在一些文本内容下正常工作的情况

现在,当我们在该列中放置一个巨大的图像时,观察右侧列如何被推到页面之外

这个问题很容易解决——而且您可能永远不会遇到它,因为此代码段在我们的样式表中非常常见

img {
  max-width: 100%;
}

但是某些元素并不那么友好。以臭名昭著的 <pre> 标签为例。假设我们在我们的 1fr 列中放入其中一个标签,其中包含一个长字符串的文本。我们又回到了崩溃状态

这次,事情没有那么容易解决!即使尝试限制 <pre> 的宽度并隐藏溢出也不会起作用

pre {
  max-width: 100%;
  overflow: hidden;
}

真正的解决方法并不难——我们只需要理解发生了什么。我不能保证我的解释 100% 正确,但我理解的方式是,网格列的最小宽度为 auto。(顺便说一句,弹性项目也是如此。)

并且由于 auto 完全基于内容,所以可以说它是“无限”大小的,其尺寸会伸缩。如果我们要在列上设置显式宽度,例如 50%400px,那么我们会说它是“确定”大小的。

要应用我们的修复,我们需要确保该列具有确定的最小宽度,而不是 auto

因此,我们可以像这样修复它

.grid {
  /* auto minimum width, causing problem */
  grid-template-columns: 1fr 300px;

  /* fix: minimum width of 0 */
  grid-template-columns: minmax(0, 1fr) 300px;
}

或者,我们在占据该网格列的元素上设置实际的 min-width在我们的简单演示中,<main> 元素会自动将其自身放置在第一列中,因为它是网格的第一个子元素。

这给了我们这个效果

main {
  min-width: 0;
}

我认为在网格定义级别执行此操作更稳健一些。无论如何,它确实有效!看到 <pre> 标签现在如何尊重列的宽度并可以按预期溢出吗?

不错。