网格项目的纵横比

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费积分!

我们之前已经介绍过 纵横比框。 它涉及使用填充的技巧,以便元素的宽度和高度按您的喜好成比例。 这并不是一个非常常见的需求,因为固定元素的高度会带来麻烦,但它确实会发生。

降低风险的一种方法是 伪元素策略,其中伪元素将父元素推到纵横比,但如果内部内容将父元素推高,它将变得更高,纵横比将被忽略。

您可以在 CSS 网格中使用这种技术,并应用于网格项目! 虽然有几种不同的应用方式值得思考。

请记住,网格区域和占据它们的元素不一定是相同的大小。

我们刚刚介绍了这一点。 这篇文章最初是本文的一部分,但感觉很重要,所以将其拆分成了一个单独的概念。

了解这一点后,就会引出这样的问题:您需要网格区域具有纵横比,而元素将在其中拉伸吗? 还是元素只需要具有纵横比,无论它位于哪个网格区域?

场景 1) 只有内部元素需要具有纵横比。

很酷。 这可以说是更容易的。 确保元素与网格区域一样宽,然后应用伪元素来处理高度拉伸的纵横比。

<div class="grid">
  <div style="--aspect-ratio: 2/1;">2/1</div>
  <div style="--aspect-ratio: 3/1;">3/1</div>
  <div style="--aspect-ratio: 1/1;">1/1</div>
</div>
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  place-items: start;
}
.grid > * {
  background: orange;
  width: 100%;
}
.grid > [style^='--aspect-ratio']::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 0;
  padding-bottom: calc(100% / (var(--aspect-ratio)));
}

这将导致 这种情况

请注意,您不需要通过自定义属性来应用纵横比。 您可以在 padding-bottom 执行重要操作的地方看到,该值可以是硬编码的,或者可以是其他任何值。

场景 2) 跨越多列以满足宽度需求

我敢打赌,您更有可能需要的是一种方法,可以让一个 2 比 1 的纵横比元素实际跨越两列,而不是被困在一列中。 执行此操作非常类似于我们上面所做的,但是需要添加一些规则来执行跨列操作。

[style="--aspect-ratio: 1/1;"] {
  grid-column: span 1;
}
[style="--aspect-ratio: 2/1;"] {
  grid-column: span 2;
}
[style="--aspect-ratio: 3/1;"] {
  grid-column: span 3;
}

如果我们也添加 grid-auto-flow: dense;,我们可以得到具有各种纵横比的元素 整齐地排列,以适合它们。

现在是时候提到一些会破坏精确纵横比的小方法了。 一些文本的 line-height 可能会使框比您想要的高度更高。 如果您想使用 grid-gap,这可能会使纵横比失效。 如果您需要对纵横比进行超精确的控制,您可能更幸运地使用硬编码值。

如果您在一个没有固定行数的网格中执行跨列操作,也会变得很棘手。 也许您正在使用 repeat/auto-fill。 您最终可能会遇到列不均匀的情况,不利于纵横比。 也许我们可以在以后再深入探讨这个问题。

场景 3) 强制执行

网格具有二维布局功能,如果我们愿意,我们可以通过强制网格区域为我们想要的高度和宽度来获得纵横比。 例如,没有什么能阻止您将高度和宽度硬编码到列和行中。

.grid {
  display: grid;
  grid-template-columns: 200px 100px 100px;
  grid-template-rows: 100px 200px 300px;
}

我们通常不会这样想,因为我们希望元素具有灵活性和流动性,因此上面使用了基于百分比的技术来实现纵横比。 但是,这是可以做到的。

查看 填充纵横比框,由 Chris Coyier (@chriscoyier) 在 CodePen 上创建。

此示例强制网格区域的大小,并使元素拉伸以填充,但您也可以固定元素的大小。

现实世界的例子

Ben Goshow 写信给我,试图实现这一点,这也是本文的灵感来源。

其中的一部分问题不仅是让框具有纵横比,还要让它们在内部具有对齐能力。 有几种方法可以解决这个问题,但我认为最简单的方法是嵌套网格。 使网格元素 display: grid; 并使用新内部网格的对齐功能。

查看 具有纵横比和内部对齐的 CSS 网格项目,由 Chris Coyier (@chriscoyier) 在 CodePen 上创建。

请注意,在此演示中,元素不是跨行,而是明确放置的(不是必需的,只是一个替代布局方法的示例)。