前言
在平常的开发中我们经常会遇到水平垂直居中的需求,水平居中比较简单:
- 行内元素水平居中:
text-align: center;
- 块级元素水平居中:
margin: auto;
垂直居中相对来说稍微麻烦一点,对于固定高度的容器,常用的方式有:
- 行内元素(inline)或表格单元格(table-cell)元素垂直居中:
vertical-align: middle;
line-height: 父元素height;
当容器宽高都不固定的情况下就更麻烦一些了,需要修改布局。接下来就总结下常用的解决方案。
本文都以宽高不固定的图片垂直居中为例
解决方案
先看下要实现的效果:
使用 flex 布局
html
<div class="box">
<div class="img-box"><img src="imgurl" alt=""></div>
<div class="img-box"><img src="imgurl" alt=""></div>
<div class="img-box"><img src="imgurl" alt=""></div>
</div>
css
.box {
display: flex;
justify-content: center;
}
.img-box {
width: 25vw;
height: 25vw;
border: 1px solid #ccc;
margin: 16px;
display: flex;
}
.img-box>img {
margin: auto;
max-width: 88%;
max-height: 88%;
}
个人认为 flex 是目前最好的解决方案。在
display: flex;
之后只需要使用margin: auto;
即可达到想要的效果。针对其他元素,flex 布局也能优雅的完成垂直居中的效果。
使用 position 绝对定位
html 同 flex 布局
css
.box {
display: flex;
justify-content: center;
}
.img-box {
width: 25vw;
height: 25vw;
border: 1px solid #ccc;
margin: 16px;
position: relative;
}
.img-box>img {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
max-width: 88%;
max-height: 88%;
}
/* 或者这样写 */
.img-box>img {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
max-width: 88%;
max-height: 88%;
}
这也是个很常见的解决方案,但是在实际开发中我们有时候不能使用绝对定位,并且绝对定位会对整体布局造成一些不可预知的问题,可能会增加我们后期维护的成本。
使用行内块法
html 同 flex 布局
css
.box {
display: flex;
justify-content: center;
}
.img-box {
width: 25vw;
height: 25vw;
border: 1px solid #ccc;
margin: 16px;
text-align: center;
}
.img-box:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.img-box>img {
display: inline-block;
vertical-align: middle;
max-width: 88%;
max-height: 88%;
}
原理就是使用 img 同级元素(这里使用的父元素的伪元素)将高度撑起,再通过
vertical-align: middle;
实现垂直居中。
此方案会增加代码量,并且做了太多 hack 操作,所以不推荐。
使用 table 布局
html
<div class="box">
<div class="img-out-box">
<div class="img-box"><img src="imgurl" alt=""></div>
</div>
<div class="img-out-box">
<div class="img-box"><img src="imgurl" alt=""></div>
</div>
<div class="img-out-box">
<div class="img-box"><img src="imgurl" alt=""></div>
</div>
</div>
css
.box {
display: flex;
justify-content: center;
}
.img-out-box {
display: table;
border: 1px solid #ccc;
margin: 16px;
}
.img-box {
width: 25vw;
height: 25vw;
display: table-cell;
text-align: center;
vertical-align: middle;
}
.img-box>img {
max-width: 88%;
max-height: 88%;
}
使用 table 布局需要更多冗余的 DOM 元素来模仿表格,所以也不推荐此方案
使用 CSS background-position 属性
此方案只适用于图片垂直居中
html
<div class="box">
<div class="img-box">
<div class="img" style="background-image: url('imgurl')"></div>
</div>
<div class="img-box">
<div class="img" style="background-image: url('imgurl')"></div>
</div>
<div class="img-box">
<div class="img" style="background-image: url('imgurl')"></div>
</div>
</div>
css
.box {
display: flex;
justify-content: center;
}
.img-box {
margin: 16px;
padding: 16px;
border: 1px solid #ccc;
}
.img {
width: 25vw;
height: 25vw;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
能实现居中完全依靠于
background-position: center;
属性
总结
我认为最佳方案还是 flex 。它写法简单,兼容性也不差,所以 flex 大法无敌!!!
PS:《CSS揭秘》写道
根据盒对齐模型(第三版)( www.w3.org/TR/css-alig… ) 的计划,在未来,对于简单的垂直居中需求,我们完全不需要动用特殊的布局模式了。因为只需要下面这行代码就可以搞定:
align-self: center;
不管这个元素还应用了其他什么属性,这样写就够了。
特地试了下,貌似现在还不支持,期待未来吧。。。