首页 > 代码库 > CSS元素水平垂直居中方法总结(方法主要来自大漠以及张鑫旭博客)

CSS元素水平垂直居中方法总结(方法主要来自大漠以及张鑫旭博客)

以下方法,由于测试环境的原因,IE系列只测试了IE9和IE6,以下所说IE的支持性只是相对于IE9和IE6来说的:


一、元素的水平垂直居中:

第一种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.m-demo {
margin: 60px 0 0 100px;
width: 500px;
height: 500px;
border: 1px solid #000000;
}

.m-demo div {
width: 200px;
height: 200px;
border: 1px solid #FF0000;
}

.g-BothCtr-1 {
position: relative;
}

.g-BothCtr-1 .cnt {
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
</style>
</head>
<body>
<div class="m-demo g-BothCtr-1">
<div class="cnt"></div>
</div>
</body>
</html>
扩展性:父元素宽高改变,子元素仍然居中,但是子元素只能固定宽高
兼容性:主流浏览器均支持,IE6不支持

这种对子元素水平垂直居中的方法兼容性很好,但是缺点是其一它需要让父元素相对定位才行,其二子元素必须为固定宽高

第二种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.m-demo {
margin: 60px 0 0 100px;
width: 500px;
height: 500px;
border: 1px solid #000000;
}

.m-demo div {
width: 200px;
height: 200px;
border: 1px solid #FF0000;
}

.g-BothCtr-2 {
text-align: center;
font-size: 0;
letter-spacing: -0.307em;
}

.g-BothCtr-2:before, .g-BothCtr-2 .cnt {
vertical-align: middle;
display: inline-block;
}

.g-BothCtr-2 .cnt {
letter-spacing: normal;
}

.g-BothCtr-2:before {
content: ‘‘;
width: 0;
height: 100%;
}
</style>
</head>
<body>
<div class="m-demo g-BothCtr-2">
<div class="cnt"></div>
</div>
</body>
</html>
/*IE6、7不支持content属性*/
扩展性:无论子元素还是父元素,元素宽高改变,子元素仍然居中
兼容性:主流浏览器均支持,IE6不支持

这种方法的缺点是子元素必须要是inline-block或者inline的元素,不能改变它的display:inline-block,也就是说子元素不能绝对定位,浮动,display设置为block

第三种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.m-demo {
margin: 60px 0 0 100px;
width: 500px;
height: 500px;
border: 1px solid #000000;
}

.m-demo div {
width: 200px;
height: 200px;
border: 1px solid #FF0000;
}

.g-BothCtr-3 {
/*对包含元素浮动的情况不适用,IE6、7不兼容*/
display: table-cell;
text-align: center;
vertical-align: middle;
}

.g-BothCtr-3 .cnt {
vertical-align: middle;
display: inline-block;
}
</style>
</head>
<body>
<div class="m-demo g-BothCtr-3">
<div class="cnt"></div>
</div>
</body>
</html>
扩展性:无论子元素还是父元素,元素宽高改变,子元素仍然居中
由于display:table-cell的原因,IE6\7不兼容

这种方法扩展性还可以,但是无论父元素还是子元素都不能浮动,如果父元素浮动,元素就只能水平居中,如果子元素浮动,则子元素按照浮动的方向走

第四种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.m-demo {
height: 300px; /*高度值不能少*/
width: 300px; /*宽度值不能少*/
border: 1px solid #000000;

}

.g-BothCtr-4 {
display: table;
position: relative;
float: left; /*可不浮动,也可浮动*/
}

.g-BothCtr-4 .tableCell {
display: table-cell;
vertical-align: middle;
text-align: center;
*position: absolute;
*top: 50%;
*left: 50%;
}

.g-BothCtr-4 .cnt {

vertical-align: center;

display: inline-block;

*position: relative;
*top: -50%;
*left: -50%;
}

/*需要注意的是,使用这种方法,如果你的居中元素是放在body中的话,你需要给html,body设置一个“height:100%”的属性。*/
</style>
</head>
<body>
<div class="m-demo g-BothCtr-4">
<div class="tableCell">
<div class="cnt">content</div>
</div>
</div>
</body>
</html>
兼容性:兼容IE6

扩展性:无论子元素还是父元素,高苦都可扩展

这种方法比上一种方法多了一个模拟table的盒子div,上面那个直接就是table-cell,因此这个是支持最外层父元素的浮动的。

这个的实现原理呢,是让最外层的元素一个display:table模拟表格,然后让内容元素的直接父元素也就是最外层父元素的下一级一个display:table-cell,让它模拟表格单元格的行为,结合text-align:center和vertical-align:middle结合子元素display:inline-block让它的子元素也就是内容元素水平垂直居中,然后IE6\7不支持table-cell怎么办呢,方法就是针对IE6\7给内容元素的直接父元素一个position:absolute,left:50%,top:50%,让它相对于最外层父元素绝对定位水平和垂直偏移50%,这个时候它的左边就和父元素的垂直基线对齐了,然后再给内容元素以position:relative,left:-50%,top:-50%;让内容元素相对于它的直接父元素往左和往上分别偏移它的直接父元素一半的距离,这个时候内容元素也就相对于最外层父元素居中了。

为什么一共需要三层标签,其一是构建table和table-cell的需要。其二,为了能够更好的在IE6\7上利用上述定位的原理进行居中。可谓一举两得,这个方法可以好好理解下

第五种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.m-demo {
margin: 50px;
width: 600px;
height: 600px;
border: 1px solid #000000;
}

.m-demo .secont {
width: 200px;
height: 200px;
background-color: #FF0000;
}

.g-horCtrHtml-1 {
text-align: center;
font-size: 0;
letter-spacing: -0.307em;
*letter-spacing: normal;
*word-spacing: -1px;
}

.g-horCtrHtml-1 .empty {
width: 100%;
height: 50%;
margin-bottom: -100px; /*配置参数,内容元素高度的一半*/
}

.g-horCtrHtml-1 .cnt {

display: inline-block;
*letter-spacing: normal;

*word-spacing: normal;
*display: inline;
*zoom: 1;
}
</style>
</head>
<body>
<div class="m-demo g-horCtrHtml-1">
<div class="empty"><!--空的内容--></div>
<div class="secont cnt">实际内容</div>
</div>
</body>
</html>
兼容性:包括IE6在内的主流浏览器都兼容
扩展性:高宽都不可扩展

这种方法虽然多了一层标签,但是兼容性好,项目中如果需要兼容IE6\7,可以考虑使用此方法

第六种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.m-demo {
margin: 50px;
width: 600px;
height: 600px;
border: 1px solid #000000;
}

.m-demo .secont {
width: 200px;
height: 200px;
background-color: #FF0000;
}

.g-horCtrHtml-1 {
text-align: center;
font-size: 0;
letter-spacing: -0.307em;
}

.g-horCtrHtml-1:before {
content: "";
display: block;
width: 100%;
height: 50%;
margin-bottom: -100px; /*配置参数,为内容元素高度一半*/
}

.g-horCtrHtml-1 .cnt {
display: inline-block;
letter-spacing: normal;
}
</style>
</head>
<body>

<div class="m-demo g-horCtrHtml-1">
<div class="secont cnt"></div>
</div>

</body>
</html>
兼容性:不兼容IE6\7
扩展性:高宽都不可扩展

这个方法只是上面那个方法的after伪元素版本,把空的标签换成了用after伪元素装载的content,由于不需要兼容IE6\7,去掉了那些hack代码

其他方法:
1、通过给内容元素一个(包含元素总宽度减去内容元素总宽度)的一半的margin-left和通过给内容元素一个(包含元素总高度减去图片总高度)的一半的margin-top的方式去居中。
2、通过给父元素一个上下相同的padding值,但是缺点是父元素不能固定高度。
3、jQuery或者js方法
4、水平居中:margin:0 auto;但是,如果你的Web页面没有明确声明"!DOCTYPE",那么在IE也会以怪异模式解析你的Web页面,此时上面这种办法将无法让你的页面实现水平居中,但你可以使用下面这种方法解决这个bug。
body {
text-align: center;/*实现IE在怪异模式下页面水平居中*/
}
.container {
text-align: left;/*让文本恢复到左对齐*/
width: 960px;/*设置页面总宽度*/
margin: 0 auto;/*使页面水平居中对
}
5、使用负数一般元素宽度margin配合绝对定位left:50%实现水平居中
6、使用负数一般元素高度margin配合绝对定位top:50%实现垂直居中

 


二、只能水平居中的方法:

第一种方法(除了能居中,还能居左,居右):
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.m-demo {
margin: 50px;
width: 400px;
height: 400px;
border: 1px solid #000000;
}

.m-demo .cnt {
width: 150px;
height: 150px;
background-color: #FF0000;
}

.g-hriLft-3, .g-hriCtr-3, .g-hriRt-outer-3, .g-hriRt-inset-3 {
font-size: 0;
letter-spacing: -0.307em;
}

.g-hriLft-3:before, .g-hriCtr-3:before, .g-hriRt-outer-3:before, .g-hriRt-inset-3:before {
content: ‘&nbsp;‘;
font-size: 0;
}

.g-hriLft-3 .cnt, .g-hriCtr-3 .cnt, .g-hriRt-outer-3 .cnt, .g-hriRt-inset-3 .cnt {
display: inline-block;
position: absolute;
letter-spacing: normal;
}

.g-hriCtr-3 .cnt {
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
-o-transform: translateX(-50%);
transform: translateX(-50%);
}

.g-hriRt-inset-3 {
text-align: right;
direction: rtl;
}

.g-hriRt-outer-3 {
text-align: right;
}

.g-hriCtr-3 {
text-align: center;
}

.g-hriLft-3 {
text-align: left;
}
</style>
</head>
<body>
<div class="m-demo g-hriRt-outer-3">
<div class="cnt"></div>
</div>
</body>
</html>
这个方法具体的解释详见张鑫旭博客:http://www.zhangxinxu.com/wordpress/2011/12/position-absolute-text-align-center/,还有很多细节没搞清楚,待我抽时间研究妥当

第二种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
body {
margin: 0;
}

.m-demo-2 {
margin: 50px 0 50px 0;
width: 100%;
height: 48px;
outline: 1px solid #000000;
}

.m-demo-2 .w div {
padding: 20px;
background-color: #FF0000;
margin-left: 5px;
}

.g-hriCtr-1 {

overflow: hidden;

}

.g-hriCtr-1:after {
/*适用于水平居中的分页列表*/
content: ".";
clear: both;
display: block;
width: 0;
height: 0;
overflow: hidden;
visibility: hidden;
}

.g-hriCtr-1 .g-ctr-w,
.g-hriCtr-1 .g-item {
float: left;
display: inline;
position: relative;
}

.g-hriCtr-1 .g-ctr-w {
left: 50%;
}

.g-hriCtr-1 .g-item {
right: 50%;
}

</style>
</head>
<body>

<div class="m-demo-2 g-hriCtr-1">
<div class="g-ctr-w w">
<div class="g-item" style="margin-left:0;"></div>
<div class="g-item"></div>
<div class="g-item"></div>
<div class="g-item"></div>
<div class="g-item"></div>
</div>
</div>

</body>
</html>
兼容性:包括IE6浏览器在内的主流浏览器都兼容
扩展性:子元素个数与大小都可扩展,父元素的高宽也可扩展。

这个方法的实现原理稍微有点绕脑筋,不过也还好,还不算难理解,不上图片,直接文字解释:

首先,给g-ctr-w 和g-item分别一个float:left,为的是让g-ctr-w和g-item的宽高都能收缩,这样,它们的大小形状就不是跟着元素的高宽走的了,而是跟着padding等除width和height外的布局属性走的了,因为float后的元素的高宽是可以收缩的,同时,给最外层的父元素清除浮动,这个不做解释,这个时候,g-ctr-w和g-item都跑到最外层父元素g-hriCtr-1的最左边去了,接下来看,如何给一个浮动的元素居中呢,其实,运用了之前的方法里面有的原理,首先分别给g-ctr-w和g-item一个position:relative,然后给g-ctr-w的left设置为50%,也就是相对于最外层父元素g-hriCtr-1往右偏移g-hriCtr的宽度一半的位移,这个时候g-ctr-w的左边就和最外层父元素g-hriCtr-1的中垂线对齐了,好,现在需要的就是让g-ctr-w往左偏移一段距离以让g-ctr-w看上去相对于最外层父元素g-hriCtr-1水平居中对齐,显然需要移动的距离是它自身宽度一半,但是你可以绞尽脑汁想想,是无论也没有一个固定的百分比值是可以让g-ctr-w总是居中的,但是,方法还是有的,我们可以给g-item的所有元素往左偏移它的父元素宽度的50%,也就是right:50%或者left:-50%,这里是用的right:50%,这样一来,看上去g-ctr-w就是相对于最外层父元素g-hrictr-1水平居中对齐了。

然后,这个高宽和子元素个数是可扩展的,但是在g-ctr-w的宽度扩展的比g-hriCtr-1的宽度一半还大时,g-hriCtr-1的父元素对超出元素的设置是超出部分显示滚动条的话,那就会出现滚动条,因此在这里,给g-hrictr-1一个overflow:hidden,将溢出空间隐藏,而g-ctr-w的的内容的宽度(包括margin)加起来比g-hrictr-1的宽度还大时,那么子元素g-item就会被挤下去。

也是个不错的方法


第三种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
body {
margin: 0;
}

.m-demo-2 {
margin: 50px 0 50px 0;
width: 100%;
height: 48px;
outline: 1px solid #000000;
}

.m-demo-2 .w div {
padding: 20px;
background-color: #FF0000;
margin-left: 5px;
}

.g-hriCtr-2 {
position: relative;
}

.g-hriCtr-2 .g-ctr-w {
position: absolute;
left: 50%;
}

.g-hriCtr-2 .g-ctr-w .g-item {
float: left;
position: relative;
right: 50%;
}

</style>
</head>
<body>

<div class="m-demo-2 g-hriCtr-2">
<div class="g-ctr-w w">
<div class="g-item" style="margin-left:0;"></div>
<div class="g-item"></div>
<div class="g-item"></div>
<div class="g-item"></div>
<div class="g-item"></div>
</div>
</div>

</body>
</html>
兼容性:包括IE6在内的主流浏览器都兼容

扩展性:内容元素高宽、个数都可扩展,但是内容元素父容器.g-ctr-w只能容纳最外层.g-hriCtr-2的宽度一半的内容,否则内容元素就会被挤出去


第四种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
body {
margin: 0;
}

.m-demo {
margin: 30px;
width: 400px;
height: 400px;
border: 1px solid #000000;
}

.m-demo div {
width: 150px;
height: 150px;
background-color: #FF0000;
}

.g-hriCtrFlex-1 {
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-pack: center;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-pack: center;
display: -o-box;
-o-box-orient: horizontal;
-o-box-pack: center;
display: -ms-box;
-ms-box-orient: horizontal;
-ms-box-pack: center;
display: box;
box-orient: horizontal;
box-pack: center;
}
</style>
</head>
<body>

<div class="m-demo g-hriCtrFlex-1">
<div></div>
</div>

</body>
</html>
由于采用的是CSS3的flex,所以兼容性不佳,只考虑在手机端使用
高宽可扩展

第五种方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
body {
margin: 0;
}

.m-demo-2 {
margin: 50px 0 50px 0;
width: 100%;
height: 48px;
outline: 1px solid #000000;
}

.m-demo-2 .w div {
padding: 20px;
background-color: #FF0000;
margin-left: 5px;
font-size: 18px;
}

.g-horCtrCSS3fitCotent {
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
margin-left: auto;
margin-right: auto;
font-size: 0;
letter-spacing: -0.307em;
}

.g-horCtrCSS3fitCotent .g-item {
display: inline-block;
letter-spacing: normal;
}
</style>
</head>
<body>

<div class="m-demo-2 g-hriCtr-1">
<div class="w g-horCtrCSS3fitCotent">
<div class="g-item" style="margin-left:0;">前端工程师</div>
<div class="g-item">前端工程师</div>
<div class="g-item">前端工程师</div>
<div class="g-item">前端工程师</div>
<div class="g-item">前端工程师前端工程师前端工程师</div>
</div>
</div>

</body>
</html>
采用的CSS3,兼容性差,只考虑在手机端使用
子元素高宽可扩展

 

CSS元素水平垂直居中方法总结(方法主要来自大漠以及张鑫旭博客)