引言

  css垂直居中一直以来都是一个被大家说烂了的话题,翻来覆去的炒。不过说实话,正是因为css没有提供标准的垂直居中方法(不过在css3中已经有了相关规范),所以大家才会对它进行专门的研究。这研究来研究去,垂直居中的方法比水平居中都要多了。但又说回来,各种方法人云亦云,不同的方法对于不同层次的人理解起来又有不同,用处也不同。本文结合技术实现的复杂度、理解性的难易度、以及大多数人的接触顺序对常用的垂直居中方法进行分等级的系统讲解,希望能对读者的工作和学习有所帮助。

  OK,闲话扯了一堆,下面开始正文,先来一个大家最先接触到的。

Level 1:绝对定位

  兼容性:

Firefox  Chrome Internet Explorer Opera Safari
(Yes) (Yes) IE8+ (Yes) (Yes)
 <div class="vertical">
<div class="content"></div>
</div>
 .vertical {
position: relative;
width: 200px;
height: 200px;
margin: 0 auto;
margin-top: 10px;
border: 1px solid blue;
}
.content {
position: absolute;
width: 50px;
height: 50px;
background-color: red;
margin: auto;
left: 0;
   right: 0;
  top: 0;
  bottom: 0;
}

  技术讲解:子元素宽高固定,设置 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)
 <div class="vertical">
<div class="content">content</div>
</div>
 .vertical {
position: relative;
width: 200px;
4 height: 200px;
5 line-height: 200px;
margin: 0 auto;
margin-top: 10px;
border: 1px solid blue;
9 font-size: 0;
}
.content {
display: inline-block;
width: 50px;
height: 50px;
background-color: red;
vertical-align: middle;
font-size: 12px;
line-height: 1.2em;
}

  或者

 <div class="vertical">
content
</div>
 .vertical {
position: relative;
width: 200px;
height: 200px;
line-height: 200px;
margin: 0 auto;
margin-top: 10px;
border: 1px solid blue;
}

  技术讲解:通过行高来实现垂直居中也是一个常常使用的方式,把行高 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)
 <div class="vertical">
<div class="content"></div>
this is test this is test this is test this is test
</div>
 1 .vertical {
display: table-cell;
width: 200px;
height: 200px;
border: 1px solid blue;
vertical-align: middle;
text-align: center;
}
.content {
display: block;
width: 50px;
height: 50px;
margin: 0 auto;
background-color: red;
}

  技术讲解:父元素设置 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) ? ?
 <div class="vertical">
<div class="content">content</div>
</div>
 .vertical {
display: block;
width: 200px;
height: 200px;
border: 1px solid blue;
writing-mode: vertical-lr;
writing-mode: tb-lr;/* 兼容IE */
}
.content {
display: block;
width: 100px;
height: 100px;
margin: auto 0;
background-image: url("img.jpg");
writing-mode: horizontal-tb;
}

  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+
 <div class="vertical">
<div class="content"></div>
<div class="content2"></div>
</div>
 .vertical {
display: flex;
flex-direction: row;
width: 200px;
height: 200px;
border: 1px solid blue;
7 justify-content: center;
align-items: center;
}
.content {
width: 50px;
height: 50px;
background-color: red;
}
.content2 {
width: 50px;
height: 80px;
background-color: green;
}

  技术讲解:随着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 布局教程:语法篇》

最常用的css垂直居中方法的更多相关文章

  1. css垂直居中方法

    CSS垂直居中的简便方法:{position:absolute;left:0;bottom:0;top:0;right:0;margin:auto;}.

  2. css 垂直居中方法汇总

    查看原文可以有更好的排版效果哦 前言 居中是平时工作中的最常见的一种需求,各种图片居中或者各种弹窗,水平居中还好,特别是垂直居中,很多初学者表示太难写了,现在列举一些常用的方法. 实战 这里只讲述cs ...

  3. css垂直居中方法盘点

    1.单行文字垂直居中 利用 line-height 即可轻松实现,如下示例: height:45px;line-height:45px; 2.多行文本固定高度垂直居中1 利用 display:tabl ...

  4. css垂直居中方法总结

    在网页布局中,我们往往会遇到下图所示的场景,让小图标和文字对齐 可能有的小伙伴会说,这个简单,直接给小图标设置左浮动来实现. 这样做是可以的,但不推荐,毕竟浮动是会影响布局的,能少用还是少用. 以前遇 ...

  5. css垂直居中方法(四)

    第六种方法,使用css的writing-mode属性,结合margin:auto. 参考文章:改变CSS世界纵横规则的writing-mode属性 传统的web流中,margin设置auto值的时候, ...

  6. css 垂直居中方法总结

    工作中遇到垂直居中问题,特此总结了一下几种方式与大家分享.本文讨论的垂直居中仅支持IE8+ 1.使用绝对定位垂直居中 HTML <div class="container"& ...

  7. [css] 垂直居中方法

    原文链接:http://www.cnblogs.com/2050/p/3392803.html 一.text-algin:center; 适用于行内元素水平居中,如图片.按钮.文字, 但是在IE67下 ...

  8. css垂直居中方法(二)

    第四种方法: 这个方法把一些div的显示方式设置为表格,因此我们可以使用表格的vartial-align属性. 代码如下: <!doctype html> <html lang=&q ...

  9. css垂直居中方法(一)

    第一种方法:首先用margin:0 auto实现水平居中,然后设置position:relative,设置top为50%(父元素高度的50%),然后设置margin-top:-150px(设置负值是因 ...

随机推荐

  1. 老李分享:webservice是什么?2

    web service 组件 基本的 web service 平台是 XML + HTTP.所有标准的 web service 使用以下组件: SOAP(简单对象访问协议) UDDI(通用描述.发现与 ...

  2. css3+js 实现砸金蛋效果

    最近闲来无事,在网上看到有人写了个砸金蛋的效果,他是没有用到css3的,当时我就感觉没什么动态效果 感觉体验不是很好,所有我就想用css3来改下,于是也来试着写写. 本来想弄个视频给你们看看效果的,但 ...

  3. Linux工具XFTP、Xshell(centos配置java环境 工具篇 总结一)

    ♣Xmanager5是什么? ♣安装XFTP ♣安装Xshell 1.Xmanager5(官网:https://www.netsarang.com/download/software.html)是全新 ...

  4. ios 获取当前设备信息、内存

    //在[UIDevice currentDevice]中的属性 @property(nonatomic,readonly,strong) NSString *name; // e.g. "M ...

  5. 为部署ASP.NET Core准备:使用Hyper-V安装Ubuntu Server 16.10

    概述 Hyper-V是微软的一款虚拟化产品,和VMWare一样采用的hypervisor技术.它已经被内嵌到Win10系统内,我们只需要进行简单的安装即可.但是前提是要确保你的机器已经启用虚拟化,可以 ...

  6. 【PAT_Basic日记】1001. 害死人不偿命的(3n+1)猜想

    还是觉得代码放这靠谱,会定期的看看和优化代码 #include <stdio.h> #include <stdlib.h> int main() { int n; int co ...

  7. STM32定时器

    /*****************************************************************************初始化定时器**************** ...

  8. HDU 5617 DP

    沿着一条条斜线DP即可,dp[k][i][j]表示第k步,一端在第j列,另一端在第i列,构成回文的个数,沿着四个方向推下去即可. #include <iostream> #include ...

  9. ashMap源码阅读与解析

    目录结构 导入语 HashMap构造方法 put()方法解析 addEntry()方法解析 get()方法解析 remove()解析 HashMap如何进行遍历 导入语 HashMap是我们最常见也是 ...

  10. springcloud(一):大话Spring Cloud

    研究了一段时间spring boot了准备向spirng cloud进发,公司架构和项目也全面拥抱了Spring Cloud.在使用了一段时间后发现Spring Cloud从技术架构上降低了对大型系统 ...