在自动填充容器中居中网格项目
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
那是因为minmax
设置的最大值太小了
您需要将最大值设置为 50%。因为你有 grid-gap:1rem
这变成 calc(50% - 1rem)
.
看到这个fiddle:
https://jsfiddle.net/1ymkg327/24/
编辑:
我现在不明白你的问题,并提出解决方案:
问题在于,使用 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;
}
弹性框
解决您问题的最有效方法可能是 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-between
、space-around
或居中,没有免费 space.
这不仅仅是网格行为。它是标准 HTML/CSS:默认情况下,div
是 block-level 元素。这意味着它占据其父元素的 100% 宽度。因此 div
无法居中(除非您覆盖默认设置)。
结构
网格中的列和行延伸到整个容器。因此,假设 auto-fill
创建了三列,则所有后续行都将具有三列。
如果第一行有三个网格项,第二行有两个网格项,则第二行还有第三列(并占用space)。因此,第二行的两项不能居中。
auto-fill
当repeat()
函数设置为auto-fill
或auto-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>
更多信息
我设置了一个包含两个项目的网格。此网格可以包含任意数量的项目,但对于此示例来说两个就足够了。
背景
在示例中,有两个灰色框向左对齐。在宽屏(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
那是因为minmax
设置的最大值太小了
您需要将最大值设置为 50%。因为你有 grid-gap:1rem
这变成 calc(50% - 1rem)
.
看到这个fiddle:
https://jsfiddle.net/1ymkg327/24/
编辑:
我现在不明白你的问题,并提出解决方案:
问题在于,使用 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;
}
弹性框
解决您问题的最有效方法可能是 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-between
、space-around
或居中,没有免费 space.
这不仅仅是网格行为。它是标准 HTML/CSS:默认情况下,div
是 block-level 元素。这意味着它占据其父元素的 100% 宽度。因此 div
无法居中(除非您覆盖默认设置)。
结构
网格中的列和行延伸到整个容器。因此,假设 auto-fill
创建了三列,则所有后续行都将具有三列。
如果第一行有三个网格项,第二行有两个网格项,则第二行还有第三列(并占用space)。因此,第二行的两项不能居中。
auto-fill
当repeat()
函数设置为auto-fill
或auto-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>