下面是《css揭秘》一书中提出的方案,站在巨人的肩膀上,记录并分享给大家

对于水平居中的,如果是内联元素,在它父级元素上设置text-align:center;,如果是块级元素,可以使用margin:auto;来让其水平居中。然而垂直居中就没那么简单了,由于场景不同,它的解决方案也多种多样。

绝对定位的方式

1
2
3
4
5
6
7
8
9
main{
position: absolute;
top: 50%;
left: 50%;
margin-top: -3em; /* 6/2 = 3 */
margin-left: -9em; /* 18/2 = 9 */
width: 18em;
height: 6em;
}

这样有一个弊端,就是要有固定的宽高;还有两种方式与上面的实现是相同的。

1
2
3
4
5
6
7
main{
position: absolute;
top: calc(50% - 3em);
left: calc(50% - 9em);
width: 18em;
height: 6em;
}

1
2
3
4
5
6
main{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

视窗单位方案

CSS Values and Units Level 3定义了一种新的单位,称为相对视窗(viewport-relative)长度单位。

  • vw是相对于视窗的宽度。与你预期刚好相反,1vw相当于视窗宽度的1%,而不是100%
  • vw相似的是,1vh相当于视窗高度的1%
  • 如果视窗的宽度小于高度,1vmin等于1vw,反之,如果视窗宽度大于高度,1vmin等于1vh
  • 如果视窗的宽度大于高度,1vmax等于1vw,反之,如果视窗宽度小于高度,1vmax等于1vh
1
2
3
4
5
6
main{
width: 18em;
padding: 1em 1.5em;
margin: 50vh auto 0;
transform: translateY(-50%);
}

Flexbox的解决方案

这无疑是最好的解决方案,因Flexbox的出现就是为了解决这样的问题。其他解决方案仍然可用,唯一原因是他们能更好的在浏览器上呈现,不过Flexbox在现代浏览器也得到更好的好支持。

1
2
3
4
5
6
7
8
body {
display: flex;
min-height: 100vh;
margin: 0;
}
main {
margin: auto;
}

Flexbox的另一个优点是,可以让匿名容器垂直居中。

1
<main>Center me, please!</main>

我们可以在和需要居中的元素

使用相同的属性,同时使用margin:auto做为备用,以于优雅降级。
1
2
3
4
5
6
7
main {
display: flex;
align-items: center;
justify-content: center;
width: 18em;
height: 10em;
}

新特性:对齐所有东西

CSS Box Alignment Level 3已经在计划,在未来我们甚至不需要使用不同的布局模式就能非常容易的实现垂直居中,我们只需要像下面这样做:

1
align-self: center;

不管元素上使用其他样式,这个将来都能运行。这听起来令人难以置信,但将来在浏览器中是可以渲染的。