CSS实现水平垂直居中方法

以前经常使用text-align: center;来实现文本居中,用margin: 0 auto;实现 div 水平居中,那么垂直居中呢?padding?这肯定是不可靠的。
其实margin: auto结合定位就可以实现水平垂直居中,你可能使用过,但是下面的几种方法不一定全部用过…

参考:如何居中任何一个元素How to Center Anything WithCSS

绝对居中(AbsoluteCentering)的工作机制可以阐述如下:

1、在普通内容流(normal content flow)中,margin:auto的效果等同于margin-top:0;margin-bottom:0。

2、position:absolute使绝对定位块跳出了内容流,内容流中的其余部分渲染时绝对定位部分不进行渲染。

3、为块区域设置top: 0; left: 0; bottom: 0; right: 0;将给浏览器重新分配一个边界框,此时该块block将填充其父元素的所有可用空间,父元素一般为body或者声明为position:relative;的容器。

4、 给内容块设置一个高度height或宽度width,能够防止内容块占据所有的可用空间,促使浏览器根据新的边界框重新计算margin:auto

5、由于内容块被绝对定位,脱离了正常的内容流,浏览器会给margin-top,margin-bottom相同的值,使元素块在先前定义的边界内居中。

这么看来, margin:auto似乎生来就是为绝对居中(Absolute Centering)设计的,所以绝对居中(Absolute Centering)应该都兼容符合标准的现代浏览器。

简而言之(TL;DR):绝对定位元素不在普通内容流中渲染,因此margin:auto可以使内容在通过top: 0; left: 0; bottom: 0;right: 0;设置的边界内垂直居中。


绝对定位

这是我使用比较多的一种居中方法,兼容性不错,支持百分比。此方法也可以扩展成固定定位居中于整个文档,不是可视区域居中,例如登录框、提示框等模态框居中。

1
2
3
4
5
6
7
8
<div class="outer-container">
<div class="center-block">
<h2>绝对定位居中</h2>
<p>父容器相对定位,容器内水平垂直居中</p>
<p>支持百分比宽高,可以控制宽高变化范围</p>
<p>利用这一方法可以做边栏效果,例如楼梯,回到顶部...</p>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.outer-container{
width: 100%;
height: 100%;
position: relative;
background-color: #549092;
}
.center-block{
width: 50%;
height: 250px;
min-width: 400px;
max-width: 600px;
padding: 20px 30px;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
overflow: auto;
background-color: #46d5da;
}

17_9_6_01.png
17_9_6_08.png

注意:最好是将样式应用在图片本身上,图片居中还可以运用单元格等其它方式实现

优点:

  1. 能兼容到IE8
  2. 支持响应式和自适应
  3. 支持图片居中

缺点:

  1. 容器可能溢出,使用overflow: auto;
  2. 宽高必须声明

注意:下面的部分样式与上面的例子重复,故省略。


负外边距

可能是最流行的居中方法,主要应用在内容块布局中,也是目前唯一能兼容到IE6的方法。

1
2
3
4
5
<div class="outer-container">
<div class="center-block">
<!-- content -->
</div>
</div>
1
2
3
4
5
6
7
8
9
.center-block{
width: 500px;
height: 200px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -250px;
}

17_9_6_02.png

优点:

  1. 兼容性很好,能兼容到IE6
  2. 较少的代码量

缺点:

  1. 宽高不可变,不支持百分比和min-/max-
  2. 容器可能溢出
  3. 负间距要考虑宽高和box-sizing属性

Translate

最简单也是比较流行的居中方法,结合绝对定位,宽高可变。

1
2
3
4
5
<div class="outer-container">
<div class="center-block">
<!-- content -->
</div>
</div>
1
2
3
4
5
6
7
.center-block{
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
}

17_9_6_03.png

优点:

  1. 高度随内容撑开
  2. 代码量少

缺点:

  1. IE8不支持
  2. 要写浏览器厂商前缀
  3. 会干扰其它transform效果
  4. 某些情况下会出现文本渲染模糊的现象

更多transform实现居中的知识可以参考Centering PercentageWidth/Height Elements


单元格(table-cell)

如果不考虑语义的话,这可能是最好的居中方法,兼容性好,高度自适应,唯一的缺点是需要两层父元素让内容块居中。

1
2
3
4
5
6
7
<div class="outer-container">
<div class="table-cell">
<div class="center-block">
<!-- content -->
</div>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
.outer-container{
display: table;
}
.table-cell{
display: table-cell;
vertical-align: middle;
}
.center-block{
width: 50%;
margin: 0 auto;
text-align: center;
}

17_9_6_04.png

优点:

  1. 高度随内容撑开
  2. 跨浏览器兼容性好

缺点:

  1. 需要额外的html元素

更多用表格单元格实现居中的知识,请参考Flexibleheight vertical centering with CSS, beyond IE7


Inline-block

一种非常聪明的居中方式,个人觉得比单元格的那种稍微要好一点,浏览器支持的也不错,只是要占用一个伪元素。

1
2
3
4
5
<div class="outer-container">
<div class="center-block">
<!-- content -->
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.outer-container{
text-align: center;
font-size: 0;
}
.outer-container:before{
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
background: salmon;
}
.center-block{
width: 50%;
font-size: 16px;
display: inline-block;
vertical-align: middle;
}

17_9_6_05.png
17_9_6_07.png

优点:

  1. 高度随内容撑开
  2. 跨浏览器兼容性好,适用于IE7

缺点:

  1. 需要额外的html元素
  2. 依赖伪元素
  3. 内容块宽度不能超过容器的100% - 0.25em。

相关知识请参考Centeringin the Unknown


Flexbox

Flex是Flexible Box的缩写,意为”弹性布局”,flex是CSS3的新增属性,它的问世目的是解决传统布局难以实现的特殊情况,例如垂直居中。Flex布局将成为未来布局的首选方案。

2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。

1
2
3
4
5
<div class="outer-container">
<div class="center-block">
<!-- content -->
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
.outer-container{
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
.center-block{
width: 50%;
overflow: auto;
}

17_9_6_06.png

优点:

  1. 宽高不用定义,随内容撑开
  2. 未来的主流居中技术
  3. 可应用于更复杂的布局技术中

缺点:

  1. IE9及以下不支持
  2. 需要添加浏览器厂商前缀

注意:应用flex布局后,其float、clear和vertical-align属性将失效。

更多flex布局方法,请参考:
A Visual Guide to CSS3 Flexbox Properties
Flex布局教程-阮一峰


建议:

  • 每种技术都有它的优势与劣势,要基于你的浏览器的支持情况,参照上面的分析,选择最合适的方法。
  • 如果不用考虑IE低版本的话,可以放心地使用Flexbox居中技术,它能优雅地实现复杂的布局情况,新属性记得一定要写浏览器前缀。
  • 在移动端浏览器上应用上面的方法可能会出现一些问题,不过问题不大,实在不行就一个个的试。

如果有错误,欢迎指正,或者如果你有更多实现居中的方式,欢迎email。