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; } .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布局
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
这里就总结这几种方法,其实解决问题的办法还有很多,而且这里只拿最简单的情况做示例,很多情况问题比这种复杂的多,需要具体问题具体分析。