我有 10 个 div (64px x 64px),我想显示最多 5 列(对于大视口和超大视口)和最少 3 列(对于 iPhone 7 等小视口)。
我正在尝试使用 CSS Grid 执行此操作,但无法执行最小列部分(即使有空间容纳 3 列,它也会达到 2 列)。
body {
background-color: wheat;
}
.parent {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(100px, 140px));
max-width: 800px;
}
.child {
height: 64px;
width: 64px;
background-color: brown;
}
<body>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</body>
网格容器的最大宽度为 800 像素。
这是 Codepen 的链接
编辑:如果可能的话,我只想使用 CSS Grid 来完成此操作,即不使用媒体查询或 Flexbox。
原文由 Sumit Bagga 发布,翻译遵循 CC BY-SA 4.0 许可协议
我一直在寻找相同的答案,但由于找不到任何有用的答案来解决这个问题,所以我设法自己解决了。这是我的解决方案,仅使用 CSS Grid 即可完美运行。
长话短说
解决方案 A - 推荐(3 - 5 列,每列最小宽度为 64px)
解决方案 B(3 - 5 列,每列宽度正好为 64px)
可重复使用的解决方案(Sass mixin)
如果你想要一个可重用的函数来轻松生成具有不同最大和最小列值的列布局,允许你在列之间添加一些间隙或调整列的最小宽度,你应该利用 Sass mixin 和 CSS 变量,如下所示:
检查我的 CodePen 以查看两个可重用解决方案(A 和 B)的完整功能示例:
https://codepen.io/btous/pen/QWvGNGm
与 flexbox 类似的方法
检查我的 CodePen 以查看使用 flexbox 的类似方法的完整功能示例:
https://codepen.io/btous/pen/OJzwdJw
让我们更深入!
了解
grid-template-columns
CSS 属性中的minmax()
函数CSS
grid-template-columns: repeat(auto-fit, minmax(min, max))
语句告诉浏览器根据元素容器自身的宽度和minmax()
min
和max
的值计算元素容器的列数---
函数。所以解决这个问题的关键是理解minmax(min, max)
函数在repeat()
函数内部是如何工作的,在grid-template-columns
CSS属性上。grid-template-columns: repeat(auto-fit, minmax(min, max)
,它会将容器分成尽可能多的列,以适应max
参数的宽度minmax()
。因此,如果我们在 500px 容器上将grid-template-columns
属性设置为minmax()
repeat(auto-fit, minmax(50px, 100px)
,它将把它分成 5 列 100px,因为这是max
的参数---
函数。minmax()
函数的第二个值小于第一个值,它取第一个值作为它的最终值,所以minmax(100px, 50px)
将得到100px。max
值设置为 1fr(1 个分数),浏览器将按照第一点和第二点中的说明运行,但采用min
值来计算列数划分容器,如果有任何剩余空间,它将在所有列之间平均分配。因此,如果我们将grid-template-columns
属性设置为repeat(auto-fit, minmax(100px, 1fr)
在具有与第二个点 (550px) 上定义的容器相同宽度的容器上,它仍将适合最多 5 列并且将具有一个 50px 的剩余空间,但这个剩余空间不会留空,而是将平均分配给所有 5 列(每列 20px),从而产生每列 120px 的 5 列布局。有关更多详细信息,请参阅此 CSS-TRICKS 帖子:
https://css-tricks.com/auto-sizing-columns-css-grid-auto-fill-vs-auto-fit
现在我们知道它是如何工作的,我们可以面对问题并逐步解决它,为 —158894822110a8a2a7de267c7-ff-7afbed8 设置
min
minmax()
max
参数。我们有两种不同的方法让
grid-template-columns
属性计算列数:min
值设置为每列所需的宽度,将max
值设置为 1frmax
值设置为我们想要的每一列的宽度,并将min
值设置为 0px,因为我们要确保min
参数永远不会高于max
一个避免它的人将被视为最终值,如第三点所述这里的要点是,如果为 ? sign 是静态的,当容器可以容纳超过所需的最大列数时,它将继续将它们添加到布局中,当容器中没有可用空间来容纳所需的最小列数时,它将继续删除它们从布局。
好的,现在我们知道我们需要让浏览器动态计算这个值,以确保它永远不会破坏我们定义的最大和最小列布局,所以让我们开始吧!
为
minmax()
函数动态计算列宽这是最棘手的部分。首先,我们需要列数永远不会超过我们想要的最大列数(在您的情况下是 5,但可以是任何值)。
要做到这一点,我们必须确保列宽永远不会超过容器宽度除以最大列数(对你来说是 5),即 100%/5,所以现在我们有以下内容:
很酷,现在布局不超过 5 列的最大值,但它总是返回 5 列布局,因为容器总是可以容纳 5 列,宽度相同除以 5。请参见下面的代码片段:
解决方案一:
解决方案B:
为了让布局在减少宽度时减少列,我们必须告诉他你想要的最小列宽,即 64px,这样它就可以在列不适合容器宽度时开始删除列。
我们将通过将
minmax()
max()
函数中来实现,该函数将采用我们的 2 个参数(所需的最小列宽,即 64px,和我们已有的那个,即 calc(100%/5)),给我们以下:请注意,我们不需要
calc()
函数在max()
中运行。使用上面的代码,只要 100%/5 的结果小于 64px,它就会将
max()
函数值设置为 64px,并且minmax()
函数将被转换为minmax(64px, 1fr)
(对于解决方案 A)或minmax(0, 64px)
(对于解决方案 B)并将容器宽度除以 64px 以计算可以容纳多少列。请参阅以下片段:解决方案一:
解决方案B:
现在我们已经正确设置了最大列数,但仍需要设置最小列数(在您的情况下为 3)。为此,我们需要确保
minmax()
的参数永远不会高于容器的三分之一,即 100%/3。我们将通过再次包装
minmax()
函数的参数来做到这一点,但在这种情况下,在min()
函数中,除了我们已经拥有的值,即max(64px, 100%/5)
,我们将添加在上一段中找到的值,结果如下:您可以在下面的代码片段中看到他们的行为:
解决方案一:
解决方案B:
允许 CSS 列间隙
至此,我们已经设置好您的布局,但是在不破坏网格的情况下为我们的网格设置一个间隙会很好,所以让我们开始吧!
如果我们想将
column-gap
属性(因为行间距不会影响我们的布局)设置为,比方说,5px,当我们计算列宽以设置布局时,我们必须将此属性带入帐户。如果没有,它将破裂。为此,我们必须从操作中减去每列的间隙,以计算
minmax()
函数的max
参数。我们可以得到每列的比例列间隙乘以
column-gap
值乘以列数减一,因为间隙总是比列少一个。这将导致:在下面的片段中查看他们的行为:
解决方案一:
解决方案B:
为任意数量的最小和最大列、任意列最小宽度和任意
column-gap
值创建可重用函数我们已经实现了我们的目标,即制作最多 5 列和最少 3 列的响应式布局,每列的最小宽度为 64px,列之间的间隙为 5px。这看起来非常好,但是如果出于某种原因我们想要更改此属性值之一或其中的某些值怎么办?我们将不得不审查
grid-template-columns
属性,并在记住并理解所有函数和数字后,将其更改为我们需要的。为什么不利用 Sass mixins 和 CSS 变量来使它变得像更改我们想要更改其变量的值一样简单,而让代码为我们完成剩下的工作呢?
We can create a mixin that takes
min-cols
,max-cols
,cols-min-width
andgrid-column-gap
as its parameters and replace the explicit values on thegrid-template-columns
他们的财产。然后在 CSS 文件的容器选择器中,我们可以包含这个 mixin 并为每个值设置一个变量,以便在我们必须更改其中任何一个时更加清楚。在 SCSS 中,它看起来像这样:
这样,我们就拥有了生成具有最大和最小列数的漂亮列布局所需的一切。