元素居中,是前端工作者一个老生常谈的话题,网上相关的资料很多,不同的人有不同的理解(不排除有直接copy的),这里我从实际项目需求出发,经过多次试验和总结,得出以下几种居中方法供大家试用并指正:
1. 单纯只是水平居中:
(1)元素宽度已知的情况下,假设为200px:
如果父元素宽度不确定,可以在父元素上添加水平方向上具体的padding值;
如果是行内块元素(或者可以变成inline-block),直接在父元素上添加 text-align:center 即可;
如果是块元素(或者可以变成block),直接在该元素上添加水平方向的margin为auto即可;
如果不想管元素的display类型,可以采用css3的弹性盒属性,代码如下:
.container{ display: flex; justify-content: center;}
如果不需要列入文档流,可以采用定位+负的外边距,代码如下:
.container{ position: relative;}.box{ position: absolute; left: 50%; margin-left:-100px;}
也可以采用定位+水平方向自动形成的外边距,代码如下:
.box{ position: absolute; left: 0; right: 0; margin: auto;}
还可以采用定位+css3新属性transform,代码如下:
.box{ position: absolute; left: 50%; transform: translateX(-50%);}
(2)元素宽度未知或者无法直接读取:
如果父元素宽度不确定,可以在父元素上添加水平方向上具体的padding值;
如果是行内块元素(或者可以变成inline-block),直接在父元素上添加 text-align:center 即可;
如果是块元素(或者可以变成block),直接在该元素上添加水平方向的margin为auto即可;
如果不想管元素的display类型,可以采用css3的弹性盒属性,代码如下:
.container{ display: flex; justify-content: center;}
如果不需要列入文档流,一般情况下是不能采用定位+水平方向自动形成的外边距,因为这样以来它的宽度就会被拉伸至和父元素一样大(或者像input这类行内块元素直接无效),甚至在IE7及以下版本的浏览器中直接无效,但对于图片而言是可以通过这种方式实现水平居中,可是到了IE7及以下版本的浏览器中还是无效;
可以采用定位+css3新属性transform,但是内容文本可能会出现自动换行的问题,所以需要加上强制不换行,代码如下:
.box{ position: absolute; left: 50%; transform: translateX(-50%);white-space: nowrap;}
(3)如果是水平居中一个浮动元素:
可以在元素外层以及容器中间套一层<div>,代码如下:
.box-wrap{ float: left;position: relative;left: 50%}.box{ float: left;position: relative;left: -50%}
需要注意三点:首先,.box的left:-50%可以换成right:50%;其次,上述的.box-wrap并不是起始的外层父元素,而是重新生成的一层嵌套元素,并且一定不能给它设置宽度;还有就是最外层,也就是第三层<div>,需要清除浮动。
也可以采用css3的弹性盒属性,代码如下:
.container{ display: flex; justify-content: center;}
注意:如果还有浮动(float:left)的兄弟元素接在后面,那么结果就变成容器中的浮动元素整体居中。
2. 单纯只是垂直居中:
(1)元素高度已知的情况下,假设为200px:
如果父元素高度不确定,可以在父元素上添加垂直方向上具体的padding值;
如果是行内块元素(或者可以变成inline-block),除了设置 vertical-align:middle,还要设置对应的父元素 line-height:容器高度(但有时候并没有实现垂直居中,而是向下偏移了一小段距离,所以需要再加父元素添加 font-size: 0;),或者在要居中的元素之前设置一个空的行内标签,假设为<span>,代码如下:
span{ display: inline-block;width: 0;height: 100%;vertical-align: middle}.box{ display: inline-block;vertical-align: middle}
如果不想管元素的display类型,可以采用css3的弹性盒属性,代码如下:
.container{ display: flex; align-items: center;}
如果不需要列入文档流,可以采用定位+负的外边距,与元素水平居中的差别只是将left换成了top;
也可以采用定位+垂直方向自动形成的外边距,与元素水平居中的差别只是将left和right换成了top和bottom;
还可以采用定位+css3新属性transform,与元素水平居中的差别只是将left和translateX换成了top和translateY;
(2)元素高度未知或者无法直接读取:
如果父元素高度度不确定,可以在父元素上添加垂直方向上具体的padding值;
如果是行内块元素(或者可以变成inline-block),除了设置 vertical-align:middle,还要设置对应的父元素 line-height:容器高度(但有时候并没有实现垂直居中,而是向下偏移了一小段距离,所以需要再加父元素添加 font-size: 0;),或者在要居中的元素之前设置一个空的行内标签,假设为<span>,代码如下:
span{ display: inline-block;width: 0;height: 100%;vertical-align: middle}.box{ display: inline-block;vertical-align: middle}
如果不想管元素的display类型,可以采用css3的弹性盒属性,代码如下:
.container{ display: flex; align-items: center;}
如果不需要列入文档流,可以采用定位+css3新属性transform,与元素水平居中的差别只是将left和translateX换成了top和translateY;
3. 同时满足水平和垂直方向的居中,请自行结合,如果不需要考虑太多兼容问题,请大胆拥抱css3新属性。
网上有人用到table和table-cell的布局方法,同样可以实现居中,但我不提倡,原因两点:一是涉及到三层嵌套,二是使用table重在表格展示,而不是网页布局。