css实现水平垂直居中

刚开始接触css就遇到过关于如何使用css实现元素的水平垂直居中的问题,后来反反复复遇到过很多次,每一次遇到这个问题都要查一下,然后问题解决了就解决了,从来没有做过总结,今天就和该问题做一个了断,来看下使用css实现元素的水平垂直居中有几种方式。

既然是居中,那肯定是个相对的概念,所以这里考虑一种最简单的情况:一个父div以及一个子div。父div给定一个名为parent的class,子div给定一个名为child的class,对应的html如下:

1
2
3
<div class="parent">
<div class="child"></div>
</div>

我们重点关注使得子元素在父元素中能够水平垂直居中的css部分代码,所以给div.parent和div.child分别加上简单的不变的样式,如下:

1
2
3
4
5
6
7
8
9
10
.parent {
background-color: green; /*方便观察给父元素加一个背景色*/
width: 300px; /*设定父元素的宽度*/
height: 200px; /*设定父元素的高度*/
}
.child {
background-color: red; /*方便观察给子元素加一个背景色*/
width: 100px; /*设定子元素的宽度*/
height: 100px; /*设定子元素的高度*/
}

下面要介绍的几种方式都将得到如下的效果:

效果图

方法一:使用position:absolute + margin:auto

1
2
3
4
5
6
7
8
9
10
11
12
.parent {
position: relative;
/*父元素设置定位是为了让子元素可以使用position:absolue*/
}
.child {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}

大致可以做以下理解:

  • 正常情况下,margin:auto使得margin-top和margin-bottom都为0,而margin-left和margin-right具有相同的不为0的值
  • 使用position:absolute,子元素脱离了文档流,文档流中其余部分渲染时,子元素不进行渲染
  • 将子元素的top,bottom,left和right都设置为0,浏览器为子元素重新分配一个边框,如果子元素没有设置宽高,则子元素将占据父元素所有可用空间
  • 给子元素设置了宽和高的值,可以防止子元素占据所有父元素的可用空间,同时,浏览器根据宽高值重新计算子元素的margin的值,margin-top和margin-bottom此时也具有相同的不为0的值
  • 此时给父元素加上padding,表现在子元素上也是重新计算了margin的值,从而一直保持居中

方法二:使用display:flex

1
2
3
4
5
.parent {
display: flex;
align-items: center;
justify-content: center;;
}
  • flex布局很方便的解决了居中问题,尤其是在移动端用起来很方便
  • flex布局还有很多其他优秀的地方,在布局方面可谓是大放异彩
  • IE8及以下的浏览器不兼容flex布局

方法三:使用transform:translate

1
2
3
4
5
6
7
8
9
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
  • 同样子元素使用绝对定位
  • top和left都设置为50%,则子元素的起点(左上角)移动到父元素的中心位置
  • 对子元素使用translate(-50%,-50%),表示(向左,向上)移动子元素(子元素宽度/2,子元素高度/2)的距离,这样就可以使得子元素中心位置和父元素中心位置重合,即子元素水平垂直对齐
  • 该方法不兼容IE8及以下

方法四:负margin

1
2
3
4
5
6
7
8
9
10
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
}
  • 同样子元素使用绝对定位
  • top和left都设置为50%,则子元素的起点(左上角)移动到父元素的中心位置
  • 将子元素设置margin-top:-(子元素高度/2);margin-left:-(子元素宽度/2)

方法五:纯粹的position定位

1
2
3
4
5
6
7
8
.parent {
position: relative;
}
.child {
position: absolute;
top: 50px;
left: 100px;
}
  • 子元素使用绝对定位
  • top的值为:(父元素高-子元素高)/2
  • left的值为:(父元素宽-子元素宽)/2

方法六:使用display:table-cell

1
2
3
4
5
6
7
8
9
.parent {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.child {
display: inline-block;
vertical-align: middle;
}
  • 父元素使用了display:table-cell所以不兼容IE6/7

这里就总结这几种方法,其实解决问题的办法还有很多,而且这里只拿最简单的情况做示例,很多情况问题比这种复杂的多,需要具体问题具体分析。

Loading comments box needs to over the wall