这个答案有两个主要部分:
了解如何对齐工作在CSS网格。
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将网格项置于中心,而不是内容(至少不是直接置于中心)。
{条
显示:inline-grid;
Grid-template-rows: 100px 100px;
Grid-template-columns: 100px 100px;
grid-gap: 3 px;
justify-items:中心;
}
节{
边框:2px纯黑色;
字体大小:3他们;
}
文章< >
< >部分X > < /部分
< >节O > < /部分
< >部分X > < /部分
< >节O > < /部分
< >部分X > < /部分
< >节O > < /部分
< >部分X > < /部分
< >节O > < /部分
< >部分X > < /部分
< / >的文章
同样的问题与对齐项:内容可能是居中作为一个副产品,但你失去了布局设计。
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>
为了集中内容,你需要采取不同的方法。再次参考网格布局的结构和范围,您需要将网格项视为父项,将内容视为子项。
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演示
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
使用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>
完整的解释请看这篇文章:
如何在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>
汽车的利润
使用边距:自动将网格项垂直和水平居中。
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>
要将网格项的内容居中,您需要将该项制成网格(或伸缩)容器,将匿名项包装在它们自己的元素中(因为CSS不能直接针对它们),并将边缘应用到新元素。
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>
盒子对齐属性
当考虑使用以下属性来对齐网格项时,请阅读上面关于自动边距的部分。
对齐项目
justify-items
align-self
justify-self
https://www.w3.org/TR/css-align-3/#property-index
text-align:中心
要在网格项中水平居中,可以使用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>
注意,对于垂直居中,垂直对齐:middle将不起作用。
这是因为vertical-align属性仅应用于内联和表单元格容器。
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建立了一个内联级容器,这是对的。那么为什么垂直对齐在网格项中不起作用呢?
原因是在网格格式化上下文中,项被视为块级元素。
6.1. 电网项目
显示
网格项的显示值被阻塞:如果
元素的流中子元素的指定显示
网格容器是一个内联级的值,它计算到它
块级等价的。
在块格式化上下文中(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%);
}
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>
下面是这个方法的完整解释:
元素将不会保持居中,特别是在调整屏幕大小时
下面是关于Grid规范中绝对定位的部分:
https://www.w3.org/TR/css3-grid-layout/#abspos