如何使用 flex/grid 将容器中的网格居中?

How to use flex/grid to center grid in a container?

尽管有很多关于居中 div 的问题,但出于某种原因,其中 none 似乎有效。作为 css 菜鸟,我和 flex/grid 在一起,我所知道的是我想要:


    <div className="flex flex-col h-screen">
      <!-- HEADER -->
      <header className="flex h-20 bg-gray-100 justify-center items-center">
        <span className="font-bold text-2xl">
          title
        </span>
      </header>
    
      <!-- BODY -->
      <div className="flex-1 flex-col mx-auto justify-center items-center max-w-screen-lge p-5">
        <div className="grid grid-cols-2 gap-4 items-center">
          <div className="flex col-span-1 h-20 items-center justify-center bg-gray-300">
            1
          </div>
          <div className="flex col-span-1 h-20 justify-end bg-gray-300">
            2
          </div>
          <div className="flex col-span-2 h-12 items-center justify-center bg-gray-300">
           3
          </div>
          <div className="flex col-span-2 h-48 items-center justify-center bg-gray-300">
            4
          </div>
          <div className="flex col-span-2 h-48 items-center justify-center bg-gray-300">
            5
          </div>
        </div>
      </div>
    
      <!-- FOOTER -->
      <footer className="flex h-20 bg-gray-100 justify-center items-center">
        <p>footer text</p>  
      </footer>
    </div>

目前看起来是这样的: layout

我如何将网格 div 置于 flex-1 容器的中心(这是否是正确的选择?)?

已编辑: parent element content (child)

不确定如何顺风执行此操作,但这是一个简单的示例,说明如何使用普通 css。

我没有以任何结构方式更改您的标记。刚刚删除了类名,以便更容易地看到是什么影响了什么。

这在微小的堆栈溢出片段中以不受欢迎的方式压缩 window(您可能需要考虑一下)因此您应该展开它以查看发生了什么。

垂直居中的关键是 .content 上的 flex 设置,它包裹了网格布局:

  • 通过display: flex
  • 使其成为弹性容器
  • 确保它与您想要居中的区域一样高,通过 min-height: 100vh
  • 在此处完成
  • 设置 flex-direction: column 使其项目垂直堆叠。 (没有这个你也可以做到,但这对我来说更有意义。)
  • 设置justify-content: center使内容居中。它垂直居中,因为这是弯曲方向轴。

您也可以通过 place-items 和 flex 或 grid 的某种组合来实现。

html, body, p {
  margin: 0;
  padding: 0;
}

.header {
  position: fixed; /* don't move, no matter what */
  top: 0; /* position fixed removes it from the normal laytou flow, so we should tell it where to be */
  left: 0;
  right: 0;
  width: 100vw;
  background: lightskyblue;
  text-align: center;
}

.footer {
  /*
  same as .header above but pinned to bottom instead of top.
  you could reduce repetition by putting the common rules in their
  own class (.fixed or whatever) and then have a secondary class for
  .top or .bottom, but this is fine for the purposes of this demo.
  */
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100vw;
  background: lightskyblue;
  text-align: center;
}

.content {
  min-height: 100vh; /* as tall as the viewport because that's where we want to be centered */
  max-width: 80vw; /* limit width */
  margin: 0 auto; /* center horizontally */

  display: flex; /* vertical centering is easy with flex */
  flex-direction: column;
  justify-content: center; /* see? */
  
  /*
  you could also accomplish the vertical centering with
  flex-direction: row (the default) and align-items: center
  instead of justify-content, but this way makes more sense to
  me for whatever reason
  */
}

.content-grid {
  display: grid; /* establish the grid container */
  grid-template-columns: repeat(2, 50%); /* for this we only need 2 equal columns */
  grid-template-rows: 70px 50px 100px 100px; /* just ballpark/eyeballed row heights to make it vaguely resemble your example image */
  gap: 1rem; /* space between the blocks */
}

.content-grid > * {
  background: aliceblue; /* just so you can see it */
}

.content-grid > :nth-child(n + 3) { /* 1n + 3 translates as 'every one-th item starting at item 3' */
  /*
  make every block after the first two occupy the entire row.
  start at gridline 1, end at the last one (aka -1)
  */
  grid-column: 1 / -1; 
}
<div>
  <!-- HEADER -->
  <header class="header">
    <span>
      title
    </span>
  </header>

  <!-- BODY -->
  <div class="content">
    <div class="content-grid">
      <div>
        1
      </div>
      <div>
        2
      </div>
      <div>
       3
      </div>
      <div>
        4
      </div>
      <div>
        5
      </div>
    </div>
  </div>

  <!-- FOOTER -->
  <footer class="footer">
    <p>footer text</p>  
  </footer>
</div>