在自动填充容器中居中网格项目

Centering grid items in an auto-fill container

我设置了一个包含两个项目的网格。此网格可以包含任意数量的项目,但对于此示例来说两个就足够了。

背景

在示例中,有两个灰色框向左对齐。在宽屏(1000 像素以上)上使用检查器,我们可以发现第三个(或更多)"shadow" 项目,它填满了 space.

的其余部分

问题

如何让方框在网格中居中?就像 "shadow" 项不存在一样。

.grid 元素上我仍然想使用网格,因为我不需要编写自动媒体查询。在包装纸上,一切皆有可能。

此外,固定宽度也不是一个选项。

.wrap {
  display: flex;
  flex-direction: column;
  /*justify-content: center;
      align-items: center;*/
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  grid-gap: 1rem;
}

.item {
  background: #eee;
}
<div class="wrap">
  <div class="grid">
    <div class="item">
      Item 1
    </div>
    <div class="item">
      Item 2
    </div>
  </div>
</div>

Fiddle

https://jsfiddle.net/1ymkg327/4/

那是因为minmax设置的最大值太小了

您需要将最大值设置为 50%。因为你有 grid-gap:1rem 这变成 calc(50% - 1rem).

看到这个fiddle:

https://jsfiddle.net/1ymkg327/24/

编辑:

我现在不明白你的问题,并提出解决方案:

https://jsfiddle.net/1ymkg327/40/

问题在于,使用 auto-fill 您创建了很多空列,这使得 justify-items:center 的行为不如您预期的那样。

您需要改用 auto-fit

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
    grid-gap: 1rem;
    justify-items:center;
}

https://jsfiddle.net/1ymkg327/36/

弹性框

解决您问题的最有效方法可能是 flexbox,因为 flex 项目不像网格项目那样局限于单个轨道 (columns/rows)。

.grid {
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 1em;
}

.item {
  flex: 1 0 100px;
  background: #eee;
  text-align: center;
  border: 1px dashed gray;
  box-sizing: border-box;
}
<div class="grid">
  <div class="item">Item 1</div>
</div>

<div class="grid">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
</div>

<div class="grid">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>

<div class="grid">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
  <div class="item">Item 4</div>
</div>

但如果您想坚持使用网格布局,这里有一些需要考虑的问题和可能的解决方案。


网格

1fr

当您说 1fr 时,就像您在代码中所做的那样,这意味着 "consume all free space"。但是没有free的时候space,就不能对齐

关键字对齐属性(即 justify-*align-*)通过免费分发 space 来工作。他们不能 left-align、right-align、space-betweenspace-around 或居中,没有免费 space.

这不仅仅是网格行为。它是标准 HTML/CSS:默认情况下,div 是 block-level 元素。这意味着它占据其父元素的 100% 宽度。因此 div 无法居中(除非您覆盖默认设置)。


结构

网格中的列和行延伸到整个容器。因此,假设 auto-fill 创建了三列,则所有后续行都将具有三列。

如果第一行有三个网格项,第二行有两个网格项,则第二行还有第三列(并占用space)。因此,第二行的两项不能居中。


auto-fill

repeat()函数设置为auto-fillauto-fit时,容器会在不溢出容器的情况下创建尽可能多的网格轨道。

使用 auto-fill,当没有网格项来填充创建的所有轨道时,将保留这些轨道。基本上,网格布局保持固定,有或没有项目。

你在问题中指出了这一点。您有两个网格项目,但其他 "shadow" 项目也存在。请注意,这些 "shadow" 项不是网格项。它们只是空的网格单元格。

由于网格单元格为空,space 没有空闲空间用于将网格项目居中。


auto-fit

auto-fit 关键字的作用与 auto-fill 相同,不同之处在于: 折叠空轨道

在您的情况下,由于您在 minmax() 函数中将 1fr 设置为 max-size,因此额外的 space 分布在两个网格项中。

同样,不可能居中,但这次是因为 fr 单元消耗了所有可用的 space(如上文 1fr 部分所述)。


justify-content: center

如上所述,无法将网格项目居中,因为行上没有空闲 space 可用于对齐目的。

解决此问题的一种方法(仍然允许灵活的列大小)是使用 max-content 而不是 1fr,以及 auto-fit.

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, max-content));
  justify-content: center;
  grid-gap: 1rem;
}

.item {
  background: #eee;
}
<div class="grid">
  <div class="item">Item 1</div>
</div>

<hr>

<div class="grid">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
</div>

<hr>

<div class="grid">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>

<hr>

<div class="grid">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
  <div class="item">Item 4</div>
</div>


更多信息