使用CSS Grid设置列的最小和最大数量

48

我有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>

网格容器的最大宽度为800px。

这里是Codepen的链接。

编辑:如果可能的话,我想只使用CSS Grid实现这个目标,即不使用媒体查询或Flexbox。

7个回答

76
我在寻找同样的答案,由于找不到任何有用的解决方案,我设法自己解决了这个问题。以下是我的解决方案,只使用CSS Grid,完美地解决了这个问题。
简而言之:
解决方案A - 推荐(3-5列,每列最小宽度为64像素)
/* Note the difference with solution B on the grid-template-columns value */

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%/3, max(64px, 100%/5)), 1fr));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%/3, max(64px, 100%/5)), 1fr));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

解决方案B(每列3-5列,每列宽度为64像素)

/* Note the difference with solution A on the grid-template-columns value */

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, min(100%/3, max(64px, 100%/5))));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, min(100%/3, max(64px, 100%/5))));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

可重复使用的解决方案(Sass mixin)
如果您想要一个可重复使用的函数,以便轻松生成具有不同最大和最小列值的列布局,允许您在列之间添加一些间隙或调整列的最小宽度,那么您应该利用Sass mixins和CSS变量,就像这样:
/* For solution A - recommended */
@mixin grid-min-max-cols($min-cols, $max-cols, $cols-min-width, $grid-row-gap: 0px, $grid-column-gap: 0px) {
  --min-cols: #{$min-cols};
  --max-cols: #{$max-cols};
  --cols-min-width: #{$cols-min-width};
  --grid-row-gap: #{$grid-row-gap};
  --grid-column-gap: #{$grid-column-gap};
  
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min((100%/var(--min-cols) - var(--grid-column-gap)*(var(--min-cols) - 1)/var(--min-cols)), max(var(--cols-min-width), (100%/var(--max-cols) - var(--grid-column-gap)*(var(--max-cols) - 1)/var(--max-cols)))), 1fr));
  gap: var(--grid-row-gap) var(--grid-column-gap);
}

/* For solution B */
@mixin grid-min-max-cols($min-cols, $max-cols, $cols-min-width, $grid-row-gap: 0px, $grid-column-gap: 0px) {
  --min-cols: #{$min-cols};
  --max-cols: #{$max-cols};
  --cols-min-width: #{$cols-min-width};
  --grid-row-gap: #{$grid-row-gap};
  --grid-column-gap: #{$grid-column-gap};
  
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, min((100%/var(--min-cols) - var(--grid-column-gap)*(var(--min-cols) - 1)/var(--min-cols)), max(var(--cols-min-width), (100%/var(--max-cols) - var(--grid-column-gap)*(var(--max-cols) - 1)/var(--max-cols))))));
  gap: $grid-row-gap $grid-column-gap;
}

.parent {
  @include grid-min-max-cols(3, 5, 64px, 5px, 5px);
}

请查看我的CodePen,以查看可重复使用的解决方案(A和B)的完全功能示例。

https://codepen.io/btous/pen/QWvGNGm

与弹性盒子相似的方法

请查看我的CodePen,以查看一个使用弹性盒子实现类似方法的完全功能示例:

https://codepen.io/btous/pen/OJzwdJw

深入了解!

理解CSS属性grid-template-columns中的minmax()函数

CSS语句grid-template-columns: repeat(auto-fit, minmax(min, max))告诉浏览器根据元素容器的宽度和minmax值来计算列数。因此,解决这个问题的关键是理解minmax(min, max)函数在repeat()函数中以及在grid-template-columns CSS属性上的工作原理。

如果我们有一个带有以下CSS属性和值的网格容器,grid-template-columns: repeat(auto-fit, minmax(min, max),它会将容器分割为尽可能多的列,其宽度由minmax()函数的max参数确定。因此,如果我们将grid-template-columns属性设置为repeat(auto-fit, minmax(50px, 100px),在一个500px的容器上,它将被分割为5个100px的列,因为这是minmax()函数的max参数。
如果容器的宽度增加到550px,它仍然可以容纳最多5列(因为要容纳另外100px的列,它至少应该有600px的宽度),但会有一个50px的剩余空间留下来。
如果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

既然我们知道它的工作原理,我们可以逐步面对问题并解决它,以便为minmax()函数设置minmax参数。

我们有两种不同的方法让grid-template-columns属性计算列数:

第一种方法,如第四点所解释的那样,是将min值设置为我们想要的每列宽度,并将max值设置为1fr。
第二种方法,如前两点所解释的那样,是将max值设置为我们想要的每列宽度,并将min值设置为0px,因为我们希望确保min参数永远不会高于max参数,以避免它被视为最终值,正如第三点所解释的那样。
这里的要点是,如果为符号设置的值是静态的,当容器可以容纳超过所需的最大列数时,它将继续将它们添加到布局中;而当容器没有足够的空间来容纳所需的最小列数时,它将从布局中删除它们。
好了,现在我们知道我们需要让浏览器动态计算这个值,以确保不会破坏我们定义的最大和最小列布局,所以让我们来做吧!
动态计算minmax()函数的列宽
这是最棘手的部分。首先,我们需要确保列数永远不超过我们所期望的最大列数(在您的情况下为5,但可以是任何值)。
为了实现这一点,我们必须确保列宽永远不超过容器宽度除以最大列数(对于您来说是5),即100%/5,所以现在我们有以下内容:
/* For solution A - recommended (note the difference with solution B on the grid-template-columns value) */
.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(100%/5), 1fr));
}

/* For solution B (note the difference with solution A on the grid-template-columns value) */
.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, calc(100%/5)));
}

酷,现在布局不超过最大的5列了,但它总是返回一个5列的布局,因为容器总是可以适应其同等宽度除以5的5列。请参见下面的片段:
解决方案A:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(100%/5), 1fr));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

解决方案B:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, calc(100%/5)));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

为了在布局缩小宽度时减少列数,我们需要告诉它你想要的最小列宽,比如64像素,这样它可以在容器宽度不适合时开始移除列。
我们将通过将minmax()函数的参数包装在一个max()函数中来实现这一点,该函数将取我们两个参数的最大值(期望的最小列宽,例如64像素,和我们已经有的值,即calc(100%/5)),得出以下结果:
/* For solution A - recommended (note the difference with solution B on the grid-template-columns value) */
.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(64px, 100%/5), 1fr));
}

/* For solution B (note the difference with solution A on the grid-template-columns value) */
.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, max(64px, 100%/5)));
}

请注意,我们不需要在max()函数内部使用calc()函数。
通过上述代码,每当100%/5的结果小于64px时,它将将max()函数的值设置为64px,并且minmax()函数将被转换为minmax(64px, 1fr)(对于解决方案A)或minmax(0, 64px)(对于解决方案B),并且会将容器宽度除以64px来计算可以容纳多少列。请参见下面的片段:
解决方案A:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(64px, 100%/5), 1fr));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

解决方案 B:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, max(64px, 100%/5)));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

现在我们已经正确设置了最大列数,但仍需要设置最小列数(在您的情况下为3)。为此,我们需要确保minmax()函数的参数永远不会超过容器的三分之一,即100%/3。
我们将通过再次包裹minmax()函数的参数来实现这一点,但这次是在一个min()函数内部,并且除了我们已经有的值max(64px, 100%/5)之外,还要加上前面段落中找到的值,结果如下:
/* For solution A - recommended (note the difference with solution B on the grid-template-columns value) */
.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%/3, max(64px, 100%/5)), 1fr));
}

/* For solution B (note the difference with solution A on the grid-template-columns value) */
.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, min(100%/3, max(64px, 100%/5))));
}

您可以在下面的片段中看到他们的行为:
解决方案 A:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%/3, max(64px, 100%/5)), 1fr));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

解决方案 B:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, min(100%/3, max(64px, 100%/5))));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

允许CSS列间隙

通过这样做,我们已经设置好了布局,但是如果我们能够在网格中设置间隙而不破坏它将会很好,所以让我们来做吧!

如果我们想要设置一个column-gap属性(因为行间隙不会影响我们的布局),比如说,5像素,当我们计算列宽以设置布局时,我们必须考虑这个属性。如果不考虑,它就会打乱。

为了做到这一点,我们必须在计算minmax()函数的max参数时,从每一列减去间隙。

我们可以通过将column-gap值乘以列数减一来得到每一列的比例间隙,因为间隙总是比列数少一个。这将导致:

/* For solution A - recommended (note the difference with solution B on the grid-template-columns value) */
.parent {
  display: grid;
  row-gap: 5px;
  column-gap: 5px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%/3 - 5px*(3-1)/3, max(64px, 100%/5 - 5px*(5-1)/5)), 1fr));
}

/* For solution B (note the difference with solution A on the grid-template-columns value) */
.parent {
  display: grid;
  row-gap: 5px;
  column-gap: 5px;
  grid-template-columns: repeat(auto-fit, minmax(0, min(100%/3 - 5px*(3-1)/3, max(64px, 100%/5 - 5px*(5-1)/5))));
}

在下面的片段中查看他们的行为:

解决方案 A:

.parent {
  display: grid;
  row-gap: 5px;
  column-gap: 5px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%/3 - 5px*(3-1)/3, max(64px, 100%/5 - 5px*(5-1)/5)), 1fr));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

解决方案B:

.parent {
  display: grid;
  row-gap: 5px;
  column-gap: 5px;
  grid-template-columns: repeat(auto-fit, minmax(0, min(100%/3 - 5px*(3-1)/3, max(64px, 100%/5 - 5px*(5-1)/5))));
}

.child {
  width: 64px;
  height: 64px;
  max-width: 100%;
}


/* Styles not related to the goal */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin-top: 0;
  text-align: center;
}

.parent {
  justify-content: space-evenly;
  margin: 0 auto;
  padding: 5px;
  border: 5px solid dodgerblue;
  background: wheat;
  overflow: hidden;
  resize: both;
}

.child {
  margin: 0 auto;
  border: 2px solid brown;
}
<p>You can resize the blue container</p>

<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>

制作一个可重用的函数,适用于任意数量的最小和最大列数,任意列的最小宽度和任意的column-gap值。
我们已经实现了我们的目标,即创建一个响应式布局,最多有5列,最少有3列,每列的最小宽度为64px,列之间的间隔为5px。这看起来非常好,但是如果出于某种原因我们想要改变其中一个属性的值或者其中一些属性的值,我们将不得不重新审查grid-template-columns属性,并在记住和理解所有的函数和数字后,将其更改为我们需要的值。
为什么不利用Sass mixins和CSS变量,使得我们只需更改变量的值,让代码为我们完成其余工作呢?
我们可以创建一个mixin,将min-cols、max-cols、cols-min-width和grid-column-gap作为参数,并将grid-template-columns属性中的显式值替换为这些参数。然后,在CSS文件中的容器选择器中,我们可以包含这个mixin,并为每个值设置一个变量,以便在需要更改任何值时更清晰明了。
在SCSS中,它会看起来像这样:
/* For solution A - recommended (note the difference with solution B on the grid-template-columns value) */
@mixin grid-min-max-cols($min-cols, $max-cols, $cols-min-width, $grid-row-gap: 0px, $grid-column-gap: 0px) {
  --min-cols: #{$min-cols};
  --max-cols: #{$max-cols};
  --cols-min-width: #{$cols-min-width};
  --grid-row-gap: #{$grid-row-gap};
  --grid-column-gap: #{$grid-column-gap};
  
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min((100%/var(--min-cols) - var(--grid-column-gap)*(var(--min-cols) - 1)/var(--min-cols)), max(var(--cols-min-width), (100%/var(--max-cols) - var(--grid-column-gap)*(var(--max-cols) - 1)/var(--max-cols)))), 1fr));
  gap: $grid-row-gap $grid-column-gap;
}

/* For solution B (note the difference with solution A on the grid-template-columns value) */
@mixin grid-min-max-cols($min-cols, $max-cols, $cols-min-width, $grid-row-gap: 0px, $grid-column-gap: 0px) {
  --min-cols: #{$min-cols};
  --max-cols: #{$max-cols};
  --cols-min-width: #{$cols-min-width};
  --grid-row-gap: #{$grid-row-gap};
  --grid-column-gap: #{$grid-column-gap};
  
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, min((100%/var(--min-cols) - var(--grid-column-gap)*(var(--min-cols) - 1)/var(--min-cols)), max(var(--cols-min-width), (100%/var(--max-cols) - var(--grid-column-gap)*(var(--max-cols) - 1)/var(--max-cols))))));
  gap: var(--grid-row-gap) var(--grid-column-gap);
}

.parent {
  @include grid-min-max-cols(3, 5, 64px, 5px, 5px);
}

有了这些,我们就可以生成一个具有最大和最小列数的漂亮的列布局了。

真遗憾我不能给这篇文章点赞两次。谢谢! - Moebius
这太棒了! - Vitor Martins
这是一个非常出色的答案。谢谢! - Tom P
第三个代码块,在“解决方案A”上为我解决了问题。谢谢! - Raphael Setin
为了使其在Firefox和Safari中正常工作,需要在min()和max()函数的计算中添加calc()。 - Daniela Witteveen
嗨 @DanielaWitteveen,抱歉回复晚了。我已在Safari 14及以上(iOS)、Safari 13.1及以上(Mac)、Windows和Mac上的Firefox中进行了测试,在所有浏览器中都一直正常工作。您确定您遇到了问题吗?能否给我更多关于您的问题的信息?谢谢! - undefined

20
你可以通过使用@media查询,在大屏幕设备上使用grid-template-columns: repeat(5, 1fr);,在小屏幕设备上使用grid-template-columns: repeat(3, 1fr),以获得所需的输出结果。

body {
  background-color: wheat;
}

.parent {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(5, 1fr);  
}

.child {
  height: 64px;
  width: 64px;
  background-color: brown;
}

@media(max-width:540px){
  .parent {
     grid-template-columns: repeat(3, 1fr);
  }
}
<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>


2
谢谢您的回答,但是有没有可能在不使用媒体查询或弹性盒子的情况下实现这个功能呢?抱歉,在发布问题后我添加了这个条件,并在问题末尾提到了它。 - Sumit Bagga
3
可能是可行的,但浏览器支持会受到限制。媒体查询将提供自由度,使您可以基于规则创建任何类型的布局.. 因此需要寻求更好的选择。 - SantoshK

8
我想这就是你正在寻找的内容。

body {
  background-color: wheat;
}

.parent {
  display: grid;
  grid-gap: 2vw;
  grid-template-columns: repeat(auto-fill, minmax(100px, 120px));
  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>

我已经更改了 - grid-template-columns: repeat(auto-fill, minmax(100px, 140px));grid-template-columns: repeat(auto-fill, minmax(100px, 120px)); 因为在小屏幕尺寸下,子元素将占用 140px 的区域,导致它在小屏幕上分成两列,现在我已将其更改为 120pxgrid-gap: 2vw; 来解决此问题。
希望这对您有所帮助。

2

我希望这能帮到您。

https://codepen.io/pandiyancool/pen/oPmgeP

层叠样式表

body {
  background-color: wheat;
}

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

.child {
  height: 80px;
  padding: 25px;
  background-color: brown;
  border: 1px solid #ccc;
  flex: 1 1 160px;
  flex-basis: 20%;
}

谢谢您的回答,但是有没有可能在不使用媒体查询或弹性盒子的情况下完成这个操作?抱歉,我应该在问题中包含这一点。现在已经编辑过了。 - Sumit Bagga
1
太晚了,有人已经踩了它 :( 我花了几分钟来做这个,现在白费了。 - Pandiyan Cool
1
赎回投票!这是一个很好的解决方案,可以帮助推荐除了被要求的选项之外的其他选择...我认为至少它不应该得到负分 :) - Frish
双倍赎回! - Andy Lorenz

0

不确定您是否介意流动列,但是使用媒体查询,您可以执行以下操作:

.parent { grid-template-columns: repeat(3, 1fr); } 适用于小屏幕

.parent { grid-template-columns: repeat(5, 1fr); } 适用于大屏幕


谢谢您的回答,但是有没有可能在不使用媒体查询或弹性盒子的情况下完成这个操作?抱歉,我应该在问题中包含这一点。现在已经编辑过了。 - Sumit Bagga
可能的话,我认为minmax是最好的选择,特别是因为你的divs是固定宽度的。 - Frish

-2

对于最大宽度的答案,@weBBer是正确的,但你应该设置最小宽度为(N)像素。


-3

我刚刚发现了一个对我有用的小技巧。我正在使用Chrome浏览器。

  grid-template-columns: repeat(7, 1fr);
  grid-template-columns: repeat(auto-fit, 1fr);


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