css居中(水平+垂直,定宽/高+不定宽/高,边距+浮动+定位)

元素居中,是前端工作者一个老生常谈的话题,网上相关的资料很多,不同的人有不同的理解(不排除有直接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;

如果不需要列入文档流,并不能采用定位+垂直方向自动形成的外边距,因为这样以来它的高度就会被拉伸至和父元素一样大,甚至在IE7及以下版本的浏览器中直接无效,但对于图片而言是可以通过这种方式实现垂直居中,可是到了IE7及以下版本的浏览器还是无效。

3. 同时满足水平和垂直方向的居中,请自行结合,如果不需要考虑太多兼容问题,请大胆拥抱css3新属性。

网上有人用到table和table-cell的布局方法,同样可以实现居中,但我不提倡,原因两点:一是涉及到三层嵌套,二是使用table重在表格展示,而不是网页布局。

posted @ 2016-10-25 22:33  衣冠小禽兽  阅读(904)  评论(0编辑  收藏  举报