又是这个老生常谈的问题,请问你如何实现水平垂直居中?这个问题在前端开发者的实际工作中和面试中遇到过无数次,相信你也有自己的一套写法,但究竟哪套方案是更好的呢,本篇文章带你看看CSS实现垂直居中的一些“奇淫巧技”
引言
说起来啼笑皆非,2013年以前,垂直居中成了CSS领域中的传说。 垂直居中,一个及其常见的需求,一个看起来相当简单的需求;在实践中确实耗费心神,百般调试,尤其是涉及尺寸不固定的元素时;过了这么久,前端猿们琢磨出了各种各样的方法........我们一起来“踩坑”
子元素定宽定高
这种的比较简单,我们用如下方式就可以轻松的将子元素水平垂直居中:
.child{
width: 200px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin: -50px -100px;
background-color: bisque;
}
这是很早的一种垂直居中的方法,必须要给子元素固定的宽高,这段css代码是这样处理的:
- 把.child元素的左上角先放置在视口(或最近的具有相对定位的祖先元素)的正中心
- 利用负外边距将元素向上向左移动,移动的距离是自身宽高的一半
这其实就实现了把元素的正中心放置在视口的正中心,这段冗长的CSS代码还可以做下优化,利用强大的calc() 函数优化掉一行代码:
.child{
width: 200px;
height: 100px;
position: absolute;
top: calc(50% - 50px);
left: calc(50% - 100px);
/* margin: -50px -100px; */
background-color: bisque;
}
效果如下图:
在实际的开发中,这种需求可能并不算多,更多的是不定宽高的元素水平垂直居中,那么这种方法就失去效果了.......
子元素不定宽高
- 表格布局法
这是比较传统的一种布局方式,它需要用到一些冗余的html元素, 这里不做过多介绍
推荐指数:☆☆
.parent{
display: table;
margin: 100px auto;
width: 400px;
height: 300px;
background-color: aquamarine;
}
.child{
display: table-cell;
text-align: center;
vertical-align: middle;
}
- 利用伪元素
个人看来这种的方式更像是一种hack手段。 推荐指数:☆☆
.parent{
margin: 100px auto;
width: 400px;
height: 300px;
background-color: aquamarine;
text-align: center;
}
.parent::before{
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.child{
display: inline-block;
vertical-align: middle;
}
- 使用translate()变形函数
当我们在translate()中使用百分比值时,是以这个元素自己的高度和宽度为基准进行换算和移动的,所以我们使用基于百分比的变形属性来对元素进行偏移,就不需要像定宽定高的元素居中那样把元素宽高写死了!
推荐指数:☆☆☆☆
.parent{
position: relative;
margin: 100px auto;
width: 400px;
height: 300px;
background-color: aquamarine;
}
.child{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: bisque;
}
我们看下效果:
现在我们已经完美实现水平垂直居中了,但用过这个方法的你一定遇见过一些坑,我们一起踩一下:
- 有时候你可能不能使用绝对定位,因为它可能会影响你整体的布局
- 如果你要居中的子元素高度比视口的高度还高,那它的顶部会被视口截掉,当然也有类似hack的手段去解决
- 这种也是比较常见的,在某些浏览器中会导致元素的显示有些模糊,尤其在移动端比较常见。这个问题可以用transform-style:preserve-3d; 来修复,这种修复手段也相当于一种hack。
这个方法起源于2013年Stack Overflow的用户,他回答了“如何使用CSS3实现垂直居中”这个问题。
- 基于Flexbox的解决方案
推荐指数:☆☆☆☆☆
flexbox是专门针对这类需求设计的,上面所说的一些方法可能在浏览器的支持程度上稍微好些,但现在浏览器对flexbox的支持度也是不错的。我们只需要少量的代码就可以实现:
- 给父元素设置display:flex;
- 给元素设置margin:auto;
.parent{
display: flex;
background-color: aquamarine;
}
.child{
margin: auto;
background-color: bisque;
}
完美~~~
当我们使用flexbox时,margin:auto;不仅仅是水平方向将元素居中,在垂直方向也是如此
使用flexbox还可以将文字水平垂直居中!一起来看下吧~~
<div class="txt">
前端搬运工Elvis Yang
</div>
.txt {
width: 300px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
}
本文至此就结束了,希望可以正在切图的你有所帮助,能选择到适合你的实现水平垂直居中的方法~~
参考书籍《CSS揭秘》