是否可以对重复和可包装的 CSS 网格中的列使用固定的最小和最大宽度?
Is it possible to use a fixed min and max width for columns in a CSS grid which are repeating and wrappable?
我想设置一个 CSS 布局,其中一个容器包含固定数量的具有以下属性的灵活宽度图块:
- 图块之间的间距是固定且一致的
- 它们的尺寸可以在固定的最小宽度和最大宽度之间扩展,但无论其内容如何,都应具有相同的宽度。在下面的示例中,我使用 100px 最小宽度和 200px 最大宽度。
- 如果它们的最小宽度不能全部水平放置在容器中,它们应该换行。
- 如果容器大得多,它们不应扩展到大于其最大固定宽度,应保持在容器的中心并且它们之间的 space 不应扩展。
也许纯CSS不可能,但感觉应该可以!下面是一个最小的例子,我将在这里详细说明:
https://jsfiddle.net/vztskh6f/1/
选项 1:CSS 网格
这似乎是最佳选择,因为我们总是希望图块宽度保持一致。为了让列换行,我相信你需要使用 repeat()
语法,而 repeat(auto-fit, ...)
似乎最适合这个用例。显而易见的解决方案似乎是使用 repeat(auto-fit, minmax(100px, 200px))
。 但是,这不起作用 无论容器的宽度如何,图块始终保持在 200px
。在其他方面,这都符合预期:
.gridContainer {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 200px));
padding: 10px;
gap: 10px;
justify-items: center;
justify-content: center;
}
.child {
width: 100%;
height: 30px;
background: #0f0;
text-align: center;
}
通过使用 grid-template-columns: repeat(auto-fit, minmax(100px, 1fr))
然后在容器上设置计算 max-width
并强制它也居中,可以通过选项 1 强制执行所需的规范,但感觉就像这样单独 CSS 网格应该可以吗?
选项 2:Flexbox
使用 flexbox 实现包装要简单得多,在 child 上使用 flex
意味着我们可以轻松地设置具有最小和最大宽度的灵活图块。然而,一旦 child 换行到第二行,它显然会扩展到其最大宽度并且与其他图块不一致:
.flexContainer {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 30px;
background: #0f0;
text-align: center;
min-width: 100px;
max-width: 200px;
// this seems to create consistent widths better than flex: 1 1 100px;
flex: 1 1 0;
// could use gap if it wasn't for Safari
margin: 0 5px 10px;
}
截图
第一行是网格布局,第二行是弹性布局,您可以看到它们在全宽下表现良好,不会超出最大宽度且它们之间的间距一致:
随着容器缩小,您可以看到网格布局项目并没有随之缩小,而是立即换行。弹性布局表现良好:
随着容器继续收缩,flex 开始包裹在所需的位置,但下一行的图块立即扩展到其最大宽度:
为了实现您想要做的事情,您需要同时处理容器和 child。
在容器上,将 min-width 设置为 100px,将最大值设为 child:
.gridContainer {
grid-template-columns: repeat(auto-fit, minmax(100px, max-content));
}
并且在每个 child 上,您将有一个固定宽度,但 max-width 为 100%,因此它会在需要时缩小:
.child {
width: 200px;
max-width: 100%;
}
已更新 fiddle:https://jsfiddle.net/7exd5hom/
我想设置一个 CSS 布局,其中一个容器包含固定数量的具有以下属性的灵活宽度图块:
- 图块之间的间距是固定且一致的
- 它们的尺寸可以在固定的最小宽度和最大宽度之间扩展,但无论其内容如何,都应具有相同的宽度。在下面的示例中,我使用 100px 最小宽度和 200px 最大宽度。
- 如果它们的最小宽度不能全部水平放置在容器中,它们应该换行。
- 如果容器大得多,它们不应扩展到大于其最大固定宽度,应保持在容器的中心并且它们之间的 space 不应扩展。
也许纯CSS不可能,但感觉应该可以!下面是一个最小的例子,我将在这里详细说明:
https://jsfiddle.net/vztskh6f/1/
选项 1:CSS 网格
这似乎是最佳选择,因为我们总是希望图块宽度保持一致。为了让列换行,我相信你需要使用 repeat()
语法,而 repeat(auto-fit, ...)
似乎最适合这个用例。显而易见的解决方案似乎是使用 repeat(auto-fit, minmax(100px, 200px))
。 但是,这不起作用 无论容器的宽度如何,图块始终保持在 200px
。在其他方面,这都符合预期:
.gridContainer {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 200px));
padding: 10px;
gap: 10px;
justify-items: center;
justify-content: center;
}
.child {
width: 100%;
height: 30px;
background: #0f0;
text-align: center;
}
通过使用 grid-template-columns: repeat(auto-fit, minmax(100px, 1fr))
然后在容器上设置计算 max-width
并强制它也居中,可以通过选项 1 强制执行所需的规范,但感觉就像这样单独 CSS 网格应该可以吗?
选项 2:Flexbox
使用 flexbox 实现包装要简单得多,在 child 上使用 flex
意味着我们可以轻松地设置具有最小和最大宽度的灵活图块。然而,一旦 child 换行到第二行,它显然会扩展到其最大宽度并且与其他图块不一致:
.flexContainer {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 30px;
background: #0f0;
text-align: center;
min-width: 100px;
max-width: 200px;
// this seems to create consistent widths better than flex: 1 1 100px;
flex: 1 1 0;
// could use gap if it wasn't for Safari
margin: 0 5px 10px;
}
截图
第一行是网格布局,第二行是弹性布局,您可以看到它们在全宽下表现良好,不会超出最大宽度且它们之间的间距一致:
随着容器缩小,您可以看到网格布局项目并没有随之缩小,而是立即换行。弹性布局表现良好:
随着容器继续收缩,flex 开始包裹在所需的位置,但下一行的图块立即扩展到其最大宽度:
为了实现您想要做的事情,您需要同时处理容器和 child。
在容器上,将 min-width 设置为 100px,将最大值设为 child:
.gridContainer {
grid-template-columns: repeat(auto-fit, minmax(100px, max-content));
}
并且在每个 child 上,您将有一个固定宽度,但 max-width 为 100%,因此它会在需要时缩小:
.child {
width: 200px;
max-width: 100%;
}
已更新 fiddle:https://jsfiddle.net/7exd5hom/