在 CSS 网格中居中

Centering in CSS Grid

我正在尝试使用 CSS 网格创建一个简单的页面。

我没有做的是将 HTML 中的文本居中放置到相应的网格单元格中。

我尝试将内容放在 left_bgright_bg 选择器内部和外部的单独 div 中,并尝试使用一些 CSS 属性来没用。

我该怎么做?

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

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  display: subgrid;
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
}

.right_bg {
  display: subgrid;
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
}

.left_text {
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  position: relative;
  z-index: 1;
  justify-self: center;
  font-family: Raleway;
  font-size: large;
}

.right_text {
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  position: relative;
  z-index: 1;
  justify-self: center;
  font-family: Raleway;
  font-size: large;
}
<div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
  </div>
</div>

<div class="right_bg">
  <!--right background color of the page-->
</div>

<div class="left_text">
  <!--left side text content-->
  <p>Review my stuff</p>

  <div class="right_text">
    <!--right side text content-->
    <p>Hire me!</p>
  </div>
</div>

你想要这个吗?

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

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  display: subgrid;
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
}

.right_bg {
  display: subgrid;
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
}

.text {
  font-family: Raleway;
  font-size: large;
  text-align: center;
}
<div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
    <div class="text">
      <!--left side text content-->
      <p>Review my stuff</p>
    </div>
  </div>

  <div class="right_bg">
    <!--right background color of the page-->
    <div class="text">
      <!--right side text content-->
      <p>Hire me!</p>
    </div>
  </div>
</div>

您可以使用 flexbox 使文本居中。顺便说一句,不需要额外的容器,因为文本被视为匿名弹性项目。

来自flexbox specs

Each in-flow child of a flex container becomes a flex item, and each contiguous run of text that is directly contained inside a flex container is wrapped in an anonymous flex item. However, an anonymous flex item that contains only white space (i.e. characters that can be affected by the white-space property) is not rendered (just as if it were display:none).

因此只需将网格项设为弹性容器 (display: flex),并添加 align-items: centerjustify-content: center 使其垂直和水平居中。

还对HTML和CSS进行了优化:

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

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  
  font-family: Raleway;
  font-size: large;
}

.left_bg,
.right_bg {
  display: flex;
  align-items: center;
  justify-content: center;
}

.left_bg {
  background-color: #3498db;
}

.right_bg {
  background-color: #ecf0f1;
}
<div class="container">
  <div class="left_bg">Review my stuff</div>
  <div class="right_bg">Hire me!</div>
</div>

尝试使用 flex:

Plunker 演示:https://plnkr.co/edit/nk02ojKuXD2tAqZiWvf9

/* Styles go here */

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

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
  display: flex;
  justify-content: center;
  align-items: center;

}

.right_bg {
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.text {
  font-family: Raleway;
  font-size: large;
  text-align: center;
}

HTML

    <div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
    <div class="text">
      <!--left side text content-->
      <p>Review my stuff</p>
    </div>
  </div>

  <div class="right_bg">
    <!--right background color of the page-->
    <div class="text">
      <!--right side text content-->
      <p>Hire me!</p>
    </div>
  </div>
</div>

甚至不要尝试使用 flex,而是使用 css 网格。只需在内容元素上添加以下内容:

place-self: center;

它会在这里做居中工作。

如果您想要将 div 内的某些内容置于网格单元格内的中心位置,您需要定义嵌套网格才能使其正常工作。 demo.

中显示的两个示例

https://css-tricks.com/snippets/css/complete-guide-grid/

这个答案有两个主要部分:

  1. 了解对齐如何在 CSS 网格中工作。
  2. 在CSS网格中居中的六种方法。

如果您只对解决方案感兴趣,请跳过第一部分。


网格布局的结构和范围

要完全了解居中在网格容器中的工作原理,首先了解网格布局的结构和范围很重要。

网格容器的HTML结构分三层:

  • 容器
  • 项目
  • 内容

在应用网格属性方面,每个级别都独立于其他级别。

网格容器的范围仅限于父子关系。

这意味着网格容器始终是父项,而网格项始终是子项。网格属性仅在此关系中起作用。

子项之外的网格容器的后代不是网格布局的一部分,并且不接受网格属性。 (至少在实现 功能之前不会,这将允许网格项的后代遵守主容器的行。)

下面是上述结构和范围概念的示例。

想象一个类似井字游戏的网格。

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
}

您希望 X 和 O 在每个单元格中居中。

因此您在容器级别应用居中:

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
  justify-items: center;
}

但是由于网格布局的结构和范围,justify-items 容器上的网格项目居中,而不是内容(至少不是直接居中)。

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
  justify-items: center;
}

section {
    border: 2px solid black;
    font-size: 3em;
}
<article>
    <section>X</section>
    <section>O</section>
    <section>X</section>
    <section>O</section>
    <section>X</section>
    <section>O</section>
    <section>X</section>
    <section>O</section>
    <section>X</section>
</article>

align-items 相同的问题:内容可能作为副产品居中,但您丢失了布局设计。

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
  justify-items: center;
  align-items: center;
}

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
  justify-items: center;
  align-items: center;
}

section {
    border: 2px solid black;
    font-size: 3em;
}
<article>
    <section>X</section>
    <section>O</section>
    <section>X</section>
    <section>O</section>
    <section>X</section>
    <section>O</section>
    <section>X</section>
    <section>O</section>
    <section>X</section>
</article>

要使内容居中,您需要采用不同的方法。再次参考grid布局的结构和范围,需要将grid item作为parent,content作为child。

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
}

section {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 2px solid black;
  font-size: 3em;
}

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
}

section {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 2px solid black;
  font-size: 3em;
}
<article>
  <section>X</section>
  <section>O</section>
  <section>X</section>
  <section>O</section>
  <section>X</section>
  <section>O</section>
  <section>X</section>
  <section>O</section>
  <section>X</section>
</article>

jsFiddle demo


在CSS网格中居中的六种方法

有多种方法可以使网格项目及其内容居中。

这是一个基本的 2x2 网格:

grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 75px;
  grid-gap: 10px;
}


/* can ignore styles below; decorative only */
grid-container {
  background-color: lightyellow;
  border: 1px solid #bbb;
  padding: 10px;
}
grid-item {
  background-color: lightgreen;
  border: 1px solid #ccc;
}
<grid-container>
  <grid-item>this text should be centered</grid-item>
  <grid-item>this text should be centered</grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>

弹性框

要使网格项目的内容居中,使用 flexbox 是一种简单易行的方法。

更具体地说,将网格项目制作成弹性容器。

此方法不存在冲突、规范违规或其他问题。它干净有效。

grid-item {
  display: flex;
  align-items: center;
  justify-content: center;
}

grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 75px;
  grid-gap: 10px;
}

grid-item {
  display: flex;            /* new */
  align-items: center;      /* new */
  justify-content: center;  /* new */
}

/* can ignore styles below; decorative only */
grid-container {
  background-color: lightyellow;
  border: 1px solid #bbb;
  padding: 10px;
}
grid-item {
  background-color: lightgreen;
  border: 1px solid #ccc;
}
<grid-container>
  <grid-item>this text should be centered</grid-item>
  <grid-item>this text should be centered</grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>

查看此 post 以获得完整解释:

  • How to Center Elements Vertically and Horizontally in Flexbox

网格布局

就像弹性项目也可以是弹性容器一样,网格项目也可以是网格容器。这个解决方案类似于上面的 flexbox 解决方案,除了居中是通过网格而不是 flex 属性完成的。

grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 75px;
  grid-gap: 10px;
}

grid-item {
  display: grid;            /* new */
  align-items: center;      /* new */
  justify-items: center;    /* new */
}

/* can ignore styles below; decorative only */
grid-container {
  background-color: lightyellow;
  border: 1px solid #bbb;
  padding: 10px;
}
grid-item {
  background-color: lightgreen;
  border: 1px solid #ccc;
}
<grid-container>
  <grid-item>this text should be centered</grid-item>
  <grid-item>this text should be centered</grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>


auto边距

使用 margin: auto 将网格项目垂直和水平居中。

grid-item {
  margin: auto;
}

grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 75px;
  grid-gap: 10px;
}

grid-item {
  margin: auto;
}

/* can ignore styles below; decorative only */
grid-container {
  background-color: lightyellow;
  border: 1px solid #bbb;
  padding: 10px;
}
grid-item {
  background-color: lightgreen;
  border: 1px solid #ccc;
}
<grid-container>
  <grid-item>this text should be centered</grid-item>
  <grid-item>this text should be centered</grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>

要使网格项目的内容居中,您需要将项目放入网格(或弹性)容器中,将匿名项目包装在自己的元素中 (),并将边距应用于新元素.

grid-item {
  display: flex;
}

span, img {
  margin: auto;
}

grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 75px;
  grid-gap: 10px;
}

grid-item {
  display: flex;
}

span, img {
  margin: auto;
}

/* can ignore styles below; decorative only */
grid-container {
  background-color: lightyellow;
  border: 1px solid #bbb;
  padding: 10px;
}
grid-item {
  background-color: lightgreen;
  border: 1px solid #ccc;
}
<grid-container>
  <grid-item><span>this text should be centered</span></grid-item>
  <grid-item><span>this text should be centered</span></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>


框对齐属性

考虑使用以下属性对齐网格项时,请阅读上面关于 auto 页边距的部分。

  • align-items
  • justify-items
  • align-self
  • justify-self

https://www.w3.org/TR/css-align-3/#property-index


text-align: center

要使网格项目中的内容水平居中,您可以使用 text-align 属性。

grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 75px;
  grid-gap: 10px;
  text-align: center;  /* new */
}


/* can ignore styles below; decorative only */
grid-container {
  background-color: lightyellow;
  border: 1px solid #bbb;
  padding: 10px;
}
grid-item {
  background-color: lightgreen;
  border: 1px solid #ccc;
}
<grid-container>
  <grid-item>this text should be centered</grid-item>
  <grid-item>this text should be centered</grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>

请注意,对于垂直居中,vertical-align: middle 将不起作用。

这是因为 vertical-align 属性 仅适用于内联和 table-cell 容器。

grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 75px;
  grid-gap: 10px;
  text-align: center;     /* <--- works */
  vertical-align: middle; /* <--- fails */
}


/* can ignore styles below; decorative only */
grid-container {
  background-color: lightyellow;
  border: 1px solid #bbb;
  padding: 10px;
}
grid-item {
  background-color: lightgreen;
  border: 1px solid #ccc;
}
<grid-container>
  <grid-item>this text should be centered</grid-item>
  <grid-item>this text should be centered</grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>

有人可能会说 display: inline-grid 建立了一个内联级容器,这是真的。那么为什么 vertical-align 在网格项中不起作用?

原因是在 grid formatting context 中,项目被视为块级元素。

6.1. Grid Item Display

The display value of a grid item is blockified: if the specified display of an in-flow child of an element generating a grid container is an inline-level value, it computes to its block-level equivalent.

block formatting context 中,vertical-align 属性 最初设计的目的是,浏览器不希望在内联级容器中找到块级元素。这是无效的 HTML.


CSS定位

最后,还有一个通用的 CSS 居中解决方案也适用于网格:绝对定位

这是将需要从文档流中删除的对象居中的好方法。例如,如果您想要:

  • ,或

只需在要居中的元素上设置position: absolute,并在将用作包含块的祖先(通常是父元素)上设置position: relative。像这样:

grid-item {
  position: relative;
  text-align: center;
}

span {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 75px;
  grid-gap: 10px;
}

grid-item {
  position: relative;
  text-align: center;
}

span, img {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}


/* can ignore styles below; decorative only */

grid-container {
  background-color: lightyellow;
  border: 1px solid #bbb;
  padding: 10px;
}

grid-item {
  background-color: lightgreen;
  border: 1px solid #ccc;
}
<grid-container>
  <grid-item><span>this text should be centered</span></grid-item>
  <grid-item><span>this text should be centered</span></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
  <grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>

以下是此方法工作原理的完整解释:

这是网格规范中关于绝对定位的部分:

CSS place-items shorthand 属性 分别设置了 align-items 和 justify-items 属性。如果没有设置第二个值,也使用第一个值。

.parent {
  display: grid;
  place-items: center;
}

这对我有用:

.d-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid black;
  border-left: 1px solid black;
}

.d-grid div {
  height: 50px;
  display: flex;
  border-bottom: 1px solid black;
  border-right: 1px solid black;
  align-items: center;
  justify-content: center;
}
<div class="d-grid">
  <div>text 1</div>
  <div>text 2</div>
  <div>text 3</div>
  <div>text 4</div>
  <div>text 5</div>
  <div>text 6</div>
</div>

我们可以在父元素中使用 place-items: center; 属性 来使子元素文本居中。

.parent {
    display:grid;
    grid-template-columns: repeat(2,1fr);
    border: 3px solid yellow;
    grid-gap: 3px;
    place-items: center;
 }
 
 .parent > div {
    background-color: blue;
    text-align: center;
    color: white;
    font-weight: bold;
    font-size: 2rem;
 }
 
 
<div class="parent">
  <div class="child1">child1</div>
  <div class="child2">child2</div>
</div>

请使用display: grid;place-content: center;看下面的代码:

<div class="parent">
    <div class="child">text</div>
</div>

.parent {
    height: 100px;
    width: 100px;
    display: grid;
    place-content: center;
    background-color: black;
}

.child {
    height: 20px;
    width: 20px;
    background-color: red;
}