在CSS网格中居中


179

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

我无法做的是将HTML文本集中到相应的网格单元格。

我尝试将内容放置在和选择器div内部和外部的单独s中,left_bgright_bg使用某些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>


1
请检查链接w3.org/Style/Examples/007/center.en.html,希望对您有所帮助。
阿里

Answers:


433

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

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

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


网格布局的结构和范围

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

网格容器的HTML 结构具有三个级别:

  • 容器
  • 该项目
  • 内容

就应用网格属性而言,每个级别都独立于其他级别。

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

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

子代以外的网格容器的后代不属于网格布局,并且不接受网格属性。(至少要等到该subgrid功能实现之后,网格元素的后代才能尊重主容器的行。)

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

想象一下像井字游戏一样的网格。

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容器在网格中心而不是内容(至少不是直接)位于网格项的中心。

在此处输入图片说明

相同的问题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;
}

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

在此处输入图片说明

jsFiddle演示


在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;
}

请参阅此帖子以获取完整说明:


网格布局

与伸缩商品也可以是伸缩容器一样,网格商品也可以是栅格容器。该解决方案与上面的flexbox解决方案类似,不同的是,居中是通过grid属性(而不是flex属性)完成的。


auto 边距

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

grid-item {
  margin: auto;
}

要使网格项目的内容居中,您需要将其放入网格(或flex)容器中,将匿名项目包装在它们自己的元素中(因为CSS不能直接将它们定位),然后将边距应用于新元素。

grid-item {
  display: flex;
}

span, img {
  margin: auto;
}


框对齐属性

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

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

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


text-align: center

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

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

这是因为该vertical-align属性仅适用于嵌入式和表格单元容器。

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

原因是在网格格式化上下文中,项目被视为块级元素。

6.1。网格项目显示

display网格项的值被块化:如果display生成网格容器的元素的流入子代的指定是内联级别的值,它将计算为其等效的块级别。

块格式化上下文中(该vertical-align属性最初是为该属性设计的),浏览器不希望在内联级容器中找到块级元素。那是无效的HTML。


CSS定位

最后,有一个通用的CSS居中解决方案也可以在Grid中使用:绝对定位

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

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

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

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

这是此方法如何工作的完整说明:

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


嗨,迈克尔,我想知道是否可以仅通过使用网格将每一列的大小调整为该行中最小列的大小?
Codesee

@TheCodesee,这可能是可行的,具体取决于您的所有要求。是否有代码示例?或者考虑发布一个包含所有详细信息的新问题。
迈克尔·本杰明

grid-containergrid-item是HTML标签吗?
diEcho

1
它们是自定义 HTML标记。您可以像本次演示一样创建自己的标签。stackoverflow.com/q/36380449/3597276 @ pro.mean
Michael Benjamin

5
这是一个很好的答案,谢谢。这使我意识到,在你的两个第一的例子,那间flexgridalign-items保持不变,但由于某种原因justify-content成为justify-items
WoJ

11

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

flexbox规格

flex容器的每个流入子元素都将成为一个flex项目,而直接包含在flex容器内的每个连续文本都将被包装在一个匿名flex项目中。但是,仅包含空格(即可能受white-space属性影响的字符)的匿名flex项目不会呈现(就像一样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>


9

甚至不要尝试使用flex;留在CSS网格!:)

https://jsfiddle.net/ctt3bqr0/

justify-self: center;
align-self: center;

在这里做对中工作。

如果要居中div放置网格单元内部的某些内容,则需要定义嵌套网格才能使其正常工作。(请查看此处显示的两个示例的小提琴。)

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

干杯!


我想知道嵌套网格。感谢您向我展示其效果。因此,您认为应该避免在网格中使用flex或将其组合起来很好吗?
甜菜根

可以组合使用,但是您需要确保使用正确的工具来完成工作。找到一些时间,观看Rachels的演讲,这将为您澄清CSS网格的主题。 youtu.be/3vJE3bVoF-Q
Konrad Albrecht

当您在网格项目上使用边框时,会发生这种方法的问题...
Andrew

2
可以将其缩短place-self: center;
DevonDahon

6

CSS place-items的简写属性分别设置align-items和justify-items属性。如果未设置第二个值,则也使用第一个值。

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

place-items目前尚不支持Edge
Konrad Albrecht

1

尝试使用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>

-2

你要这个?

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>


1
不完全的。文本也应垂直对齐。
甜菜根

使用.text{ font-family: Raleway; font-size: large; text-align: center; -webkit-transform: rotate(-90deg); -moz-transform: rotate(-90deg); }
Renato siqueira

-2

我知道这个问题已经有几年历史了,但是我很惊讶地发现没有人建议:

   text-align: center;

这是比证明内容更通用的属性,并且绝对不是网格所独有的,但是我发现,在处理文本时(这是该问题专门询问的问题),它使文本与中心对齐而不影响空间在网格项目之间或垂直居中。它在垂直轴上水平放置文本。我还发现它消除了一层证明内容和align-items增加的复杂性。justify-content和align-items影响整个网格项,text-align使文本居中而不影响其所在的容器。希望这会有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.