CSS 的垂直居中

在 CSS 中对元素进行水平居中是非常简单的:如果它是一个行内元素, 就对它的父元素应用”text-align:center”; 如果它是一个块级元素,就对它自身应用”margin:auto”。
目前垂直居中有几种技巧十分流行:
基于绝对定位
当我们在 translate() 变形函数中使用百分比值时,是以这个元素自身的宽度和高度为基准进行换算和移动的,而这正是我们所需要的。接下来,只要换用基于百分比的 CSS 变形来对元素进行偏移,就不需要在偏移量中把要垂直居中的元素的尺寸写死了。在某些浏览器中,这个方法可能会导致元素的显示有一些模糊,因 为元素可能被放置在半个像素上。这个问题可以用”transform-style:preserve-3d”来修复,不过这个修复手段也可以认为是一个 hack。

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

基于父元素容器居中,也可以不使用绝对定位和 left、top。

main {
  width: 18em;
  padding: 1em 1.5em;
  margin: 50% auto 0; 
  transform: translateY(-50%);
}

基于 viewport
把元素相对于视口进行居中,【CSS Values and Units Module Level 3】(https://www.w3.org/TR/css-values-3/#relative-lengths) 定义了一套新的单位,称为 viewport 相关的长度单位。
vw :1% of viewport’s width
vh :1% of viewport’s height
vmin :1% of viewport’s smaller dimension
vmax :1% of viewport’s larger dimension
相对于视口垂直居中适用于外边距的是 vh 单位:

main {
  width: 18em;
  padding: 1em 1.5em;
  margin: 50vh auto 0; 
  transform: translateY(-50%);
}

基于 Flexbox
Flexbox 是专门针对这类需求所设计的,因为目前现代浏览器对 Flexbox 的支持度已经相当不错了,所以这是毋庸置疑的最佳解决方案。使用 Flexbox 时,”margin: auto”不仅在水平方向上将元素居中,垂直方向上也是如此,而且不需要指定任何宽度(当然,如果需要的话,也是可以指定的):这个居中元素分配到的宽度等于 max-content。
我们只需写两行声明即可:
先给这个待居中元素的父元素设置 “display:flex”(在这个例子中是 <body> 元素)。
再给这个元素自身设置我们再熟悉不过的 “margin:auto”(在这个例子中是 <main> 元素)。

body {
  display: flex;
  min-height: 100vh;
  margin: 0;
}
main {margin: auto;}

Flexbox 的另一个好处在于,它还可以将匿名容器(即没有被标签包裹的文本节点)垂直居中。举个例子,假设我们的结构代码是:

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

我们先给这个 main 元素指定一个固定的尺寸,然后借助 Flexbox 规范 所引入的 align-items 和 justify-content 属性,我们可以让它内部的文本也实现居中:

main {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18em;
  height: 10em;
}

相关文章: