垂直居中

垂直居中需求极其常见,实现的方法也多样,总结几个方法

基于绝对定位的垂直居中

1
2
3
4
5
6
7
position: absolute;
top: 50%;
right: 50%;
width: 12em;
height: 8em;
margin-top: -4em;
margin-right: -6em;

别忘了,若是垂直居中某个标签当中,需要设置此标签relative定位

可以借用calc减少两行声明,注意减号前后有空格!!!

1
2
3
4
5
position: absolute;
top: calc(50% - 4em);
right: calc(50% - 6em);
width: 12em;
height: 8em;


以上方法的局限在于要求元素的宽高固定,如果我们能知道一个属性的百分比能代表元素本身的宽高,那就能解决问题,对于绝大多数CSS属性(包括margin)来说,百分比都是以父元素的尺寸为基准解析的

但是!!CSS变形属性,在translate()变形函数中使用百分比值时,是以这个元素自身的宽高为基准解析的,这正是我们需要的

1
2
3
4
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);


缺点:
首先有时不能选择绝对定位,这对整个布局影响很大;
其次当垂直居中的元素高度超过了窗口,它的顶部会被视口裁切掉;
最后在某些浏览器里可能会出现元素显示有一些模糊,因为元素可能被放置在半个像素上,可以用transform-style: preserve-3d来解决;

基于视口单位的垂直居中

先介绍一下与视口相关的长度单位
vw与视口宽度相关的,1vw是视口宽度的1%;
vh与视口高度相关的,1vh是视口高度的1%;
vmin视口宽度和高度小的那个,视口宽度小于视口高度则1vmin=1vw,反之1vmin=1vh
vmax视口宽度和高度大的那个,视口宽度大于视口高度则1vmax=1vw,反之1vmax=1vh
so,如果不用绝对定位,可以用基于视口来达到定位的效果

1
2
margin: 50vh auto 0;
transform: translateY(-50%);

vertical-centering-vh

这种方式的缺点呢,就是只能做基于视口的垂直居中

基于Flexbox的垂直居中

这种方式是最优解,伸缩盒就是为这种需求所设计的,先给待居中元素的父元素设置display: flex,再给自身元素设置margin: auto

1
2
3
4
5
6
7
8
9
10
11
12
.wrapper{
display: flex;
width: 20em;
height: 12em;
background: #fb3;
}
.inner{
margin: auto;
width: 12em;
height: 8em;
background: #4a4a4a;
}


Flexbox还有一个好处,就是可以为匿名容器(没有被标签包裹的文本节点)垂直居中,例如
1
<main>Center me ,Please!</main>


首先为该元素设定尺寸,然后设置align-itemsjustify-content

Center me ,Please!