使用CSS网格在固定宽度列中居中

4

我试图制作一个简单的CSS居中网格布局。 我知道当我使用justify-items: center时,容器内的项目应该水平对齐,但是当我像这样指定像素列宽grid-template-columns: repeat(3, 100px)时,整个网格就恢复正常了。那么有没有办法使网格项目居中,同时指定像素列宽? 以下是我的示例:

    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>

.container {
    background-color: #aa96da;
    display: grid;
    justify-items: center;
    grid-gap: 20px;
    grid-template-rows: repeat(3, 1fr);

    /*Only if I change this 100px to '1fr' the justify-items will work */
    grid-template-columns: repeat(3, 100px);
}

.item {
    width: 100px;
    height: 100px;
    background-color: green;
}

你想如何将宽度为100像素的项目居中放置在同样宽度的列中?没有空间进行居中。 - Temani Afif
我想要的是将整个网格容器居中放置在页面主体内,而不是将特定网格项居中。 - Adolin
3个回答

5

justify-items 改为 justify-content,它就会起作用。

.container {
    background-color: #aa96da;
    display: grid;
    /* justify-items: center; */
    justify-content: center;
    grid-gap: 20px;
    grid-template-rows: repeat(3, 1fr);

    /*Only if I change this 100px to '1fr' the justify-items will work */
    grid-template-columns: repeat(3,  100px);
}

.item {
    width: 100px;
    height: 100px;
    background-color: green;
}
 <div class="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>


2

简短回答: 您需要使用 justify-content 而不是 justify-items

.container {
  background-color: #aa96da;
  display: grid;
  justify-content: center; /* -items to -content */
  grid-gap: 20px;
  grid-template-rows: repeat(3, 1fr);
  /*Only if I change this 100px to '1fr' the justify-items will work */
  grid-template-columns: repeat(3, 100px);
}

.item {
  width: 100px;
  height: 100px;
  background-color: green;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>


长答案:

网格项和其所在空间之间有区别。

当您定义网格时,您只定义称为tracks的网格的行/列,而不是实际定义每个元素放置的位置等。

DOM元素只遵循网格流并相应地放置,我们可以使用属性如grid-column grid-row进行修改。

您可以这样看待它: enter image description here

正如您所看到的,有The Grid containerThe GridThe ColumnsThe RowsThe Grid items

网格项位于两者之间的交汇处,称为The Grid Area(这使得CSS网格在某些方面比flexbox更好)

justify-items将网格项对齐在该区域内。


因此,grid-template-columns: repeat(3, 1fr);表示三列,它们的宽度是网格的宽度平均分配给它们。

演示

不要看代码,只看预览

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

[grid] {
  height: 300px;
  display: flex;
  border: 2px solid;
  padding: 10px;
  flex-wrap: wrap;
}

[column] {
  flex: 1 0 calc(100% / 3);
  border: 2px solid;
  display: flex;
  flex-direction:column;
  align-items:center;
  
}

[column]>div {
  width: 100px;
  flex:1;
  background-color: green;
}
<div grid>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
</div>

如您所见,网格列比网格项100px宽,这意味着有空间来居中对齐内容,因此justify-items: center;会将其居中对齐。

这就是为什么它看起来像网格已经居中对齐了,但实际上并非如此。这也是为什么更改为grid-template-columns: repeat(3, 100px);会破坏它的原因。


grid-template-columns: repeat(3, 100px);的情况下

Demo

请不要看代码,只看预览

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

[ctr] {
  border: 2px solid;
  padding: 10px;
}

[grid] {
  height: 300px;
  width: 340px;
  display: flex;
  padding: 10px;
  flex-wrap: wrap;
}

[column] {
  flex: 0 0 100px;
  border: 2px solid;
  display: flex;
  flex-direction: column;
  align-items: center;
}

[column]>div {
  width: 100px;
  flex: 1;
  background-color: green;
}
<div ctr>
  <div grid>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
  </div>
</div>

正如您所看到的,列宽等于网格项的宽度,因此它们都可以完美地适合列中,而网格仍然是空的。


哦,谢谢,这完全解决了问题!此外,我重新阅读了你的答案两次,终于明白了网格布局是如何工作以及justify-itemsjustify-content的含义。 - Adolin
@Adolin 如果你想要更深入的解释,请参考网格布局中的盒子对齐 - Rainbow

0

您可以尝试在这些网格元素上方添加 flex 属性,然后使用 justify-content:center; 将其居中。

  • index.html:
<div class="centering_items">
       <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
      </div>
</div>
  • style.css
.centering_items {
    display: flex;
    justify-content: center;
}

.container {
    background-color: #aa96da;
    display: grid;
    grid-gap: 20px;
    grid-template-rows: repeat(3, 1fr);

    /*Only if I change this 100px to '1fr' the justify-items will work */
    grid-template-columns: repeat(3,  100px);
}

.item {
    width: 100px;
    height: 100px;
    background-color: green;
}

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