最常用的css垂直居中方法
引言
css垂直居中一直以来都是一个被大家说烂了的话题,翻来覆去的炒。不过说实话,正是因为css没有提供标准的垂直居中方法(不过在css3中已经有了相关规范),所以大家才会对它进行专门的研究。这研究来研究去,垂直居中的方法比水平居中都要多了。但又说回来,各种方法人云亦云,不同的方法对于不同层次的人理解起来又有不同,用处也不同。本文结合技术实现的复杂度、理解性的难易度、以及大多数人的接触顺序对常用的垂直居中方法进行分等级的系统讲解,希望能对读者的工作和学习有所帮助。
OK,闲话扯了一堆,下面开始正文,先来一个大家最先接触到的。
Level 1:绝对定位
兼容性:
Firefox | Chrome | Internet Explorer | Opera | Safari |
---|---|---|---|---|
(Yes) | (Yes) | IE8+ | (Yes) | (Yes) |
1 <div class="vertical"> 2 <div class="content"></div> 3 </div>
1 .vertical { 2 position: relative; 3 width: 200px; 4 height: 200px; 5 margin: 0 auto; 6 margin-top: 10px; 7 border: 1px solid blue; 8 } 9 .content { 10 position: absolute; 11 width: 50px; 12 height: 50px; 13 background-color: red; 14 margin: auto; 15 left: 0; 16 right: 0; 17 top: 0; 18 bottom: 0; 19 }
技术讲解:子元素宽高固定,设置 position: absolute,top 和 bottom 设置为0之后可以实现自适应垂直居中,同理也可以实现水平居中。垂直居中是大多数人最早开始接触到的垂直居中方法,实现简单,理解起来也不复杂,兼容性强,在实际中的运用也比较广泛。但是因为元素使用绝对定位会脱离文档流,所以这种方法常常用来对对话框和弹窗进行定位,也常常用于对界面基础结构进行布局。(如下)
技术要点:绝对定位的定位参照物为第一个具有非 static 定位的祖先元素,所以父元素的 position 属性必须是非 static 的属性才能实现垂直居中,且子元素需设置 margin: auto。
优点:实现简单,易理解,兼容性强,适用于多种场景,自适应性强。
缺点:只能对 block 元素进行垂直居中,切会脱离文档流,所以使用的时候需要注意。
Level 2:行高
兼容性:
Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|
(Yes) | (Yes) | IE8+ | (Yes) | (Yes) |
1 <div class="vertical"> 2 <div class="content">content</div> 3 </div>
1 .vertical { 2 position: relative; 3 width: 200px; 4 height: 200px; 5 line-height: 200px; 6 margin: 0 auto; 7 margin-top: 10px; 8 border: 1px solid blue; 9 font-size: 0; 10 } 11 .content { 12 display: inline-block; 13 width: 50px; 14 height: 50px; 15 background-color: red; 16 vertical-align: middle; 17 font-size: 12px; 18 line-height: 1.2em; 19 }
或者
1 <div class="vertical"> 2 content 3 </div>
1 .vertical { 2 position: relative; 3 width: 200px; 4 height: 200px; 5 line-height: 200px; 6 margin: 0 auto; 7 margin-top: 10px; 8 border: 1px solid blue; 9 }
技术讲解:通过行高来实现垂直居中也是一个常常使用的方式,把行高 line-height 和 高度 height 设置为相同值,可实现子元素垂直居中。子元素只能是 inline 类型或者 inline-block 类型,需要注意的是,通过这种方式实现的垂直居中,一行文字的行高也就是整个父元素的高度(包括 inline 元素如 <span> ,inline-block 元素如 <img>),因此文本内容只能显示一行,其余的则会溢出。如果子元素是 inline-block 类型,那么需要设置 vertical-align: middle,不过这不是绝对的垂直居中。相信大家也看见前面画横线的部分,出现了奇怪的 font-size:0,这是因为 inline-block 类型对齐的只是文本的基线(baseline),而不是文本的中线(关于基线和中线,来源于 inline-box 的概念,详情可参见张鑫旭的文章:css行高line-height的一些深入理解及应用)。所以需要设置 font-size:0 ,来使 inline-box 模型的高度为0,这样其中线和基线就在一条线上了。同时还需要注意的是,由于line-height 和 font-size 的继承性,所以在子元素上需要对其进行修复。使用行高进行垂直居中是非常普遍的应用,由于其可以控制子元素垂直居中,所以常常用来制作导航栏的样式。(如下)
技术要点:将 line-height 和 height 设置为相同值实现垂直居中。inline 类型的子元素只能显示一行文字,inline-block 类型的子元素要注意其对齐的是基线,因此要通过设置 font-size:0 来实现绝对垂直居中。
优点:兼容性强,实现简单,可对 inline-block 以及 inline 类型的元素垂直居中。
缺点:需要对其父元素进行完全的控制,且 inline 类型子元素文本只能显示一行,灵活性不强。
Level 3:表格单元(table-cell)
兼容性:
Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|
(Yes) | (Yes) | IE8+ | (Yes) | (Yes) |
1 <div class="vertical"> 2 <div class="content"></div> 3 this is test this is test this is test this is test 4 </div>
1 .vertical { 2 display: table-cell; 3 width: 200px; 4 height: 200px; 5 border: 1px solid blue; 6 vertical-align: middle; 7 text-align: center; 8 } 9 .content { 10 display: block; 11 width: 50px; 12 height: 50px; 13 margin: 0 auto; 14 background-color: red; 15 }
技术讲解:父元素设置 display:table-cell,并将垂直对齐方式设置为 vertical-align:middle 可实现子元素垂直居中。使用 table-cell 进行垂直居中也是一个较常用的方法,该方法比用 line-height 更灵活,但是其父元素因为具有表格的属性稍微较难控制,因此最好的是在外面再加一层 wraper 。这种方法实现垂直居中,子元素为 inline、inline-block、block均可,且没有使用行高那样只能显示一行文本的限制,并且具有自适应性。(相关实例目前我还没有发现o( ̄▽ ̄)d )
技术要点:设置父元素 displate:table-cell 以及 vertical-align:middle 实现垂直居中,必要时建议加上一个 wraper。
优点:子元素可以为多种类型的元素,block、inline-block、inline 类型均可,使用范围广,且具有自适应性。
缺点:父元素具有表格属性,因为较难控制,建议使用时加上一个 wraper。
Level 4: writing-mode
兼容性:
Chrome | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|
8+ | 41+ | IE8+(partial) | ? | ? |
1 <div class="vertical"> 2 <div class="content">content</div> 3 </div>
1 .vertical { 2 display: block; 3 width: 200px; 4 height: 200px; 5 border: 1px solid blue; 6 writing-mode: vertical-lr; 7 writing-mode: tb-lr;/* 兼容IE */ 8 } 9 .content { 10 display: block; 11 width: 100px; 12 height: 100px; 13 margin: auto 0; 14 background-image: url("img.jpg"); 15 writing-mode: horizontal-tb; 16 }
Chrome & FireFox
IE
技术讲解:通过 writing-mode 来实现垂直居中相信大多数人都没有听说过,不过该方法也几乎没有见过在实际中的运用,除了改变文本方向之外。相信我们所有人在最开始学习到块元素水平居中 margin:0 auto 的时候,都曾幻想加一个 auto 来实现垂直居中,but it doesn't work。但是现在我们要回来了,我们要使用 margin 来实现垂直居中,writing-mode 的作用是改变文档流的方向,因为浏览器的文档流方向默认是从上到下,从左向右,我们把前后顺序换一下,换成从左向右,从上到下,这样一来原来的 width 变成了 height,原来的 height 变成了width,从而使盒模型转换了90度。也就是说一切的排版规则不变,只是原本站立的人现在趟下了,之前的一切特性也会跟着一起躺下,比如外边距 margin 等等。如果说只是用于实现垂直居中的话,子元素要修复文档流方向,因为 writing-mode 具有继承性。不过在IE上就不那么乐观了,IE有其自身实现 writing-mode 的值,在这里就不一一列举了。在IE当中如果修复子元素的话,子元素本身也会被修复,也就是说子元素本身的排版会按照修复属性的样式,这里大家可以自行测试。这种方法还有一个需要注意的是,改变文档流的方向并不会改变其背景图片的排版方向。此方法实际运用意义不大,并且兼容性不好(只是单纯的针对IE而已。。。),拿它来炫技是个不错的选择。
技术要点:设置父元素 writing-mode: vertical-lr 改变文档流方向,子元素设置 margin: auto 0 实现垂直居中,如有必要给子元素加上 writing-mode: horizontal-tb 修复文档流。
优点:自适应性强,与绝对定位实现效果类似,且不会脱离文档流。
缺点:实用性不大,兼容性差,只能对 block 类型元素实现垂直居中。
Level 5:flex布局
兼容性:
Chrome | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|
21+ | 28+ | 10+(partial) | 12.1+ | 6.1+ |
1 <div class="vertical"> 2 <div class="content"></div> 3 <div class="content2"></div> 4 </div>
1 .vertical { 2 display: flex; 3 flex-direction: row; 4 width: 200px; 5 height: 200px; 6 border: 1px solid blue; 7 justify-content: center; 8 align-items: center; 9 } 10 .content { 11 width: 50px; 12 height: 50px; 13 background-color: red; 14 } 15 .content2 { 16 width: 50px; 17 height: 80px; 18 background-color: green; 19 }
技术讲解:随着CSS3的到来,我们终于有了官方标准的垂直居中方法,flex布局是w3c针对复杂的文档模式新提出来的一种布局方案,目前浏览器兼容性还算乐观,随着IE市场的衰减,flex布局将会成为未来布局的主流。这种布局方法灵活多变,可适应不同的文档流和各种场合。其中使其垂直居中生效的方法是 justify-content 和 align-items ,不过要注意主轴 flex-direction 的方向,默认值是 row(及水平的文档流),注意这里和传统的默认从上到下的文档流相反。justify-content 设置主轴上的对齐方式,也就是相对于主轴的水平对齐方式,aligh-items 设置交叉轴的对齐方式,也就是相对于主轴的垂直对齐方式。关于具体的 flex 布局教程,可以参加大漠的《图解CSS3:核心技术与案例实战》,或者阮一峰的文章Flex 布局教程:语法篇。虽说目前为止 Flex 布局对于IE的兼容性不完整,但是在移动端 Flex 可是已经大有作为了,并且今后随着IE用户逐渐转移到edge上,flex布局将会代替许多传统的方法。
技术要点:父容器设置 display:flex 使用 flex 布局,通过 flex-direction 设置主轴方向再用 justify-content 和 aligh-items 设置水平或垂直方向的对齐方式,注意主轴方向与对齐方向的关系。
优点:适用范围广,自适应性强,灵活性高,可对任意类型子元素实现垂直居中。
缺点:目前兼容不完善(只是目前为止)。
总结
垂直居中的方法五花八门,细数起来肯定不只这5种,但是归根到底其实现的思想和技术核心却是一样的。以上5种方法是对不同垂直居中方法的一个总结,排名顺序依照技术实现的难易度、可理解性的复杂度、以及大多数人的接触顺序的综合分析。目前浏览器的兼容性测试还不够完全,如有错误或者补充,欢迎在评论中指出。
以上 DEMO 运行平台: Windows 10 & FireFox 54
在线测试平台:jsfiddle
参考文献:
大漠 —— 《图解CSS3:核心技术与案例实战》
张鑫旭 —— 《改变CSS世界纵横规则的writing-mode属性》
张鑫旭 —— 《css行高line-height的一些深入理解及应用》
阮一峰 —— 《Flex 布局教程:语法篇》