具有最大宽度项的响应式CSS网格布局

3
我希望能够自动生成一个网格,始终填满可用空间,同时缩小项目,直到可以添加另一个项目。
大多数响应式网格实现使用类似以下的方式:
grid-template-colums: repeat(auto-fill, minmax(120px, 1fr));

这个代码可以正常运行,但是默认图像大小使用最小值,导致网格内的图像插值。我想做相反的操作 - 设置一个最大宽度,如果需要则缩小图像。

假设我的网格项应该有最大宽度为400像素。以下是我想要获取的一些值:

400px available space: One image with a width of 400px
402px available space: Two images with a width of 201px
800px available space: Two images with a width of 400px
and so on …

基本上,我想将我的图像夹在200px和400px之间,并始终使用可能的最大值。我想我需要这样的东西:
min(max(200px, 1fr), 400px)

到目前为止,我唯一能够实现这一点的方法是通过生成一些媒体查询。

/* This example adjusts items to a max-width of 400px with a 10px grid-gap.*/

@media (min-width: 401px) {
  .grid {
    grid-template-columns: repeat(auto-fill, calc((100% - 10px) / 2));
  }
}
@media (min-width: 811px) {
  .grid {
    grid-template-columns: repeat(auto-fill, calc((100% - 20px) / 3));
  }
}

我已经编写了一个Sass mixin来使这个过程更加灵活,但是这种解决方案有一些缺点:
  • 您必须生成任意数量的查询来处理多个屏幕尺寸,这可能会导致死代码
  • 您必须知道网格容器的可用空间以进行媒体查询(或使用的空间来计算可用空间)
我正在寻找一种没有这些缺点的方法。

编辑:

这里是我的当前代码的CodePen链接。如果你在其中玩耍,应该更容易理解我想做什么。

1个回答

2

目前来看,你的媒体查询方案可能是最好的选择。

当前,CSS Grid 不支持灵活的最小值。

根据规范:

minmax(min, max)

定义大于或等于 min 且小于或等于 max 的大小范围。

如果 max < min,则忽略 max 并将 minmax(min,max) 视为 min

作为最大值,<flex> 值设置轨道的 flex 因子;它无效作为最小值。

注意:本规范的未来版本可能允许使用 <flex> 最小值,并将更新轨道大小算法以正确处理此内容。

你是否考虑过使用 flexbox:

.grid {
  display: flex;
  flex-wrap: wrap;
}

.grid > div {
  flex: 1 0 200px;  /* can grow, can't shrink, minimum width 200px */
  max-width: 400px;
  margin: 5px;
}

.grid-item {
  width: 100%;
  height: auto;
}
<div class="grid">
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
  <div><img src="http://placehold.it/400x300" alt="" class="grid-item"></div>
</div>

修改后的codepen


1
好主意,更广泛的浏览器支持将是一个额外的好处。然而,最后一行不太理想。你能想到一个简单的方法来让最后一项与其他项目具有相同的大小吗?即使它们没有填满整行。 - Afterlame
在最后一行上调整 flex 项目的大小是一个已知的问题。我在这里列出了几个解决方案:https://dev59.com/flgQ5IYBdhLWcg3w0HOW - Michael Benjamin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接