网上的css水平垂直的教程非常多,不管你是实际需求遇到问题还是为了应付一些面试,都应该把css水平垂直居中给学好,这是作为前端的必备技能。
这里我会给大家说最简单最实用兼容性都非常好的版本,这样就可以在短时间内获取到性价比最高的知识,终身受益!

首先谈谈css水平垂直居中的实现方式:
假设dom结构是这样的:

1
2
3
<div class="box">
<div class="content"></div>
</div>

并且已知父子元素各自的宽高:

1
2
3
4
5
6
7
8
9
10
.box {
width: 400px;
height: 400px;
background: #4cf;
}
.content {
width: 200px;
height: 200px;
background: #f4c;
}

  1. 50%absolute + 负margin,这也是我比较喜欢的方式。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .box {
    position: relative;
    }
    .content {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -100px;
    margin-top: -100px;
    }

因为absolute的left和top设置50%之后,子元素左上角的点就会距离父元素左上角的点各50%(父元素宽高的50%),此时利用margin的值可以是负值的特性,再让子元素往左、往上”回去”各50%(子元素宽高的50%),即可实现水平垂直都居中。

  1. absolute 全部0 + margin: auto
    这个是利用absolute+margin的第二个版本,代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .box {
    position: relative;
    }
    .content {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    }

很多人都用过margin: auto;来实现块级元素水平居中,那么就会有人思考,如果是margin: auto;是不是就能水平垂直都居中呢,答案是否认的,你需要先用absolute把上下左右都归零。

  1. absolute + transform实现居中:
    这个方法其实和第一个是一样的思路第一个方法是用margin可以是负值这一特性,来实现子元素往回移动的,这个方法是使用css3的transform下的translate来实现往回移动的,这两种方式最后实现的效果是一样的,只是使用的方式不同,因此也因为使用方式不同而产生了兼容性的不同,此方法因为使用了css3的transform属性,导致兼容性很高,文章末尾我会给出兼容性表格。下面是代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    .box {
    position: relative;
    }
    .content {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    -moz-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
    -o-transform: translate(-50%, -50%);
    }
  2. lineheight + vertical-align + text-align 这个也是我比较喜欢的方式,目前是我最常用的方式。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .box {
    line-height: 400px;
    text-align: center;
    }
    .content {
    display: inline-block;
    vertival-align: middle;
    /* 如果你的子元素中有文字可以加上下边的 */
    text-align: center;
    }
  3. table-cell模拟table,与第4类似:
    table是可以用来实现水平垂直居中的,但是我没有写table,因为使用table的方式实现居中,会出现很多麻烦的代码,如果你确定自己非常喜欢table,不想放弃它。
    那么你可以使用table-cell,它可以实现table的效果还不用出现冗余代码,兼容性也还不错。

    1
    2
    3
    4
    5
    6
    7
    8
    .box {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    }
    .content {
    display: inline-block;
    }
  4. 先有flex后有天,无敌布局赛神仙!
    有了flex,就等于有了一切 —— 鲁迅
    flex是一个近乎无敌的布局神器,当然他也有一些劣势,不过日常用的话趋近于无敌了,然后就是兼容性需要考虑,因为flex的兼容性是IE10+,在IE10以下的时候是不起作用滴。

    1
    2
    3
    4
    5
    .box {
    display: flex;
    justify-content: center;
    align-items: center;
    }

有了flex,布局就是这么简单!

下面呢,是我总结的这几种方案的兼容性表格:
当然,大家也可以去www.caniuse.com来查询更加详细的兼容性。

方式PC兼容性移动端兼容性
负marginIE6、chrome4、firefox2Android2.3+、IOS6+
margin: autoIE6、chrome4、firefox2Android2.3+、IOS6+
transformIE9、chrome4、firefox4Android4.4+、IOS6+
line-heightIE6、chrome4、firefox2Android2.3+、IOS6+
table-cellIE8、chrome4、firefox2Android2.3+、IOS6+
flexIE10、chrome4、firefox2Android2.3+、IOS6+

整理的时候遇到了一个神奇的css属性:
writing-mode
这玩意能改变文本方向,并且改变以后,所以水平上的属性,都会自动变成垂直方向上的属性,我们也可以使用这种方法实现水平垂直居中,但是代码量有点多,稍微有点麻烦。
另外就是这玩意居然被firefox支持的晚一些,不过也正常,毕竟大多数的前端都不认识这个属性。
感兴趣的小伙伴们可以去google一下试试。