问题场景

应用的地方比较普遍,这里有两个赤裸裸的栗子:

 

也有很多流行的方案,这里只针对各种方案的适用场景来做一些分析

问题抽象

其实,垂直居中问题可以简化成这样:一个容器HTML元素(#container),一个需要居中的HTML元素(#center)。特殊的情形下可能会出现body为#container,#center是图片,此处不予讨论。 #center 可能有高度,也可能没有,也可能是响应式的。总之,代码的结构如下图所示:


再有就是浏览器的兼容性问题:IE6,IE7.....不说了,都是泪。总之,我们要做的就是在相应的代码处填入代码以期达到下图目的。:

方案一:负外边距(Negative Margins)

这种方案应该是最流行的,思路也比较简单,浏览器的兼容性(IE6+)也比较好,但是必须要指定#center的高度,也无法进行响应式处理(类似height:60%,max-width:400px;)

 
如果能确定#center高度,并且无需响应式,这种方案是最棒的!

方案二:绝对定位居中(Absolute Centering)

该方法兼容IE8+,虽然可以自适应,虽然padding可以不用操心,但是还是必须声明高度!关于这种方案的工作原理:

  • 在普通内容流(normal content flow)中,margin:auto的效果等同于margin-top:0;margin-bottom:0。
  • position:absolute使绝对定位块跳出了内容流,内容流中的其余部分渲染时绝对定位部分不进行渲染。
  • 为块区域设置top: 0; left: 0; bottom: 0; right:
    0;将给浏览器重新分配一个边界框,此时该块block将填充其父元素的所有可用空间,父元素一般为body或者声明为position:relative;的容器。
  • 给内容块设置一个高度height或宽度width,能够防止内容块占据所有的可用空间,促使浏览器根据新的边界框重新计算margin:auto
  • 由于内容块被绝对定位,脱离了正常的内容流,浏览器会给margin-top,margin-bottom相同的值,使元素块在先前定义的边界内居中。
  • 总之:绝对定位元素不在普通内容流中渲染,因此margin:auto可以使内容在通过top: 0; left: 0; bottom: 0;right: 0;设置的边界内垂直居中。

方案三:变形(Transforms)

这种方案是方案一的一种延伸,它解决了方案一必须指定高度,不支持响应式的问题,但是浏览器兼容性不佳,只支持IE9+,但是在移动版的浏览器却可以放心的使用哦!


另外,这种方案可能需要在transform上加入前缀,不过如果有less和sass这样的东西就好多了,瞬间,又有了对IE的鄙视!

方案四:表格单元格(table-cell)

思路是这样的: <table><tr><td>I am Centered</td></tr></table>,代码是这样的:

  • 1.需要木有语义的多余的标签嵌套
  • 2.兼容IE8+
  • 3.可能在一些浏览器上有问题(特别是IE)

由于兼容上的一些问题,这个方案,不太建议。

方案五:行内块元素(inline-block)

思路为:期望在#container中:text-align:center;,在#center中:vertical-align:middle;达到目的,但是#center却无法撑开#container,咋办呢?
可以在#container里面加入一个多余的display为inline-block的div(作为#container的一个child),将#container的高度撑开,就像这样:


如果支持:before或者:after的浏览器,就可以高大山一些:


但是,还存在如下两个问题:

  • 由于两个inline-block的元素之间默认是有间隙的,所以需要在#center中margin-right为负值或者在#container中font-size:0px;(如果#center为图片的情况下)进行调整
  • #center的宽度不能大于#container的100%-间隙,否则before将会被挤走

方案六:Flexbox

这个应该是最简单的,如下:


原理为:margin:auto;自动获取伸缩容器中剩余的空间,设置垂直方向margin值为auto,可以使伸缩项目在伸缩容器的两上轴方向都完全集中。我觉得,实际上相当于这样:


关于Flexbox,请参见 这里
但是flex的缺点也是显而易见的,不支持老旧的浏览器。

总结

以上各种方案,各有优缺,希望大家赶紧提建议,我也将能够通用的代码全部整到了github上(这里

参考

  • http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/
  • http://www.w3cplus.com/css3/a-guide-to-flexbox.html
  • http://www.smashingmagazine.com/2013/05/22/centering-elements-with-flexbox/
  • http://www.zhangxinxu.com/wordpress/2010/10/%E6%88%91%E6%89%80%E7%9F%A5%E9%81%93%E7%9A%84%E5%87%A0%E7%A7%8Ddisplaytable-cell%E7%9A%84%E5%BA%94%E7%94%A8/
  • http://www.zhangxinxu.com/wordpress/2013/11/margin-auto-absolute-%E7%BB%9D%E5%AF%B9%E5%AE%9A%E4%BD%8D-%E6%B0%B4%E5%B9%B3%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD/
  • http://www.zhangxinxu.com/wordpress/2009/08/大小不固定的图片、多行文字的水平垂直居中
  • http://designshack.net/articles/css/how-to-center-anything-with-css
  • http://css-tricks.com/centering-in-the-unknown/
  • https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform

CSS垂直居中解决方案的更多相关文章

  1. CSS的水平居中和垂直居中解决方案

    在写CSS样式的时候,有时为了美观,会添加水平居中和垂直居中,这时候你有可能会遇到很棘手的问题,有些水平居中和垂直居中的属性添加上去完全没反应,下面给大家列举一些CSS水平居中和垂直居中的终极解决方案 ...

  2. css 完美垂直居中解决方案兼容ie8以上等其他浏览器

    css 完美垂直居中解决方案兼容ie8以上等其他浏览器 <pre><!DOCTYPE html><html><head> <title>DI ...

  3. CSS水平居中和垂直居中解决方案

    一.CSS 居中 — 水平居中 DIV等标签本身没有定义自己居中的属性,网上很多的方法都是介绍用上级的text-align: center,然后嵌套一层DIV来解决问题. 可是这个方法有时候完全不起作 ...

  4. css 垂直居中技巧

    CSS垂直居中技巧,我只会23个,你会几个?自古以来(是有多?~),网页CSS的垂直居中需求始终没有停过,而其困难度也始终没有让人轻松过,经过了每位开发先烈的研究后,据说CSS的垂直居中技巧已达到近十 ...

  5. CSS垂直居中指南

    大概整理下css中的垂直居中问题 主要分两大类 1 知道块元素尺寸,一般就是指知道元素高度. 方法一:最简单的,类比水平居中. 思路:子元素设置为absolute;  top bottom都设置为0 ...

  6. 最常用的css垂直居中方法

    css垂直居中一直以来都是一个被大家说烂了的话题,翻来覆去的炒.不过说实话,正是因为css没有提供标准的垂直居中方法(不过在css3中已经有了相关规范),所以大家才会对它进行专门的研究.这研究来研究去 ...

  7. css垂直居中方法

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

  8. CSS垂直居中完美有用实例

    <!DOCTYPE HTML>           <html>            <head>             <meta meta chars ...

  9. Day14:CSS垂直居中

    verticle-align:middle vertical-align:middle实现css垂直居中是常用的方法,但是需要注意,vertical生效的前提是diaplay:inline-block ...

随机推荐

  1. eclipse使用Git插件

    折腾了会Git,记录一下下. 1.安装Git  Help-->Install New Software  点击Add,Name随意,Location为http://download.eclips ...

  2. Javascript自定义类

    JavaScript并不是严格的面向对象的语言,但是带有面向对象的一些特性,我们可以通过这些特性创建js中的自定义类. JavaScript中的类其实是function关键字包裹的一系列变量和方法. ...

  3. 元器件选型(一)ESD、TVS参考资料

    许多开发人员都遇到过这样的情况:在实验室开发好的产品,测试完全通过,但到了客户手里用了一段时间之后,出现异常现 象,甚至是产品失效需要返修,并且故障率往往也不高(1%以下).一般情况下,以上问题大都由 ...

  4. java学习:AWT组件和事件处理的笔记(1)--菜单条,菜单,菜单项

    菜单放在菜单条里,菜单项放在菜单里1.MenuBar    在java.awt包中,负责创建菜单条,即MenuBar的一个实例,便是一个菜单条.    在Frame类中的setMenuBar(Menu ...

  5. 软件看门狗--别让你地程序无响应(使用未公开API函数IsHungAppWindow,知识点较全)

    正文一.概述一些重要的程序,必须让它一直跑着:而且还要时时关心它的状态——不能让它出现死锁现象.当然,如果一个主程序会出现死锁,肯定是设计或者编程上的失误.我们首要做的事是,把这个Bug揪出来.但如果 ...

  6. 【深夜急报,Win10下的Linux子系统之Bash】

    [在Windows下进行的编程人员,你真的需要学习下Linux] 手册:<Linux 命令手册(特洛伊版2.0)> 链接: https://pan.baidu.com/s/1skrVSvV ...

  7. COCI 2015/2016 Day 8 PROKLETNIK

    PROKLETNIK 题目描述:给出\(n\)个数,定义一段连续的数为魔法串是该区间的左右端点值正好是区间的最小值与最大值(最小值可以在左也可以在右,最大值也一样).\(Q\)个询问,每次询问一个区间 ...

  8. 关于清晰讲解linux正则表达式的博文分享

    http://www.cnblogs.com/chengmo/archive/2010/10/10/1847287.html  linux shell 正则表达式(BREs,EREs,PREs)差异比 ...

  9. 操作hadoop的经验积累

    操作hadoop的经验积累 Hadoop namenode –format 在执行格式化-format命令时,要避免namenode的namdespaceid与datanode的namespaceid ...

  10. 聚类算法初探(四)K-means

    最近由于工作需要,对聚类算法做了一些相关的调研.现将搜集到的资料和自己对算法的一些理解整理如下,供大家参考. 另外在算法代码方面,我也做了一些实现(包括串行和并行),欢迎感兴趣的朋友探讨和交流. 第一 ...