CSS实现垂直居中的五种方法

    CSS有许多方法可以实现垂直居中,但是选择合适的方法却很难。我将为你展示我见过的所有的最棒的方法以及如何创建一个精致小巧的居中网页。 
        使用CSS实现垂直居中并不是一件容易的事,有许多不同的方法,其中一些可能在某些浏览器中不生效。让我们来看看五种不同的垂直居中的方法和它们各自的优缺点(你可以看看我的测试页面(http://douglasheriot.com/tutorials/css_vertical_centre/demo4.html),它简明扼要地解释了所有这些方法)。 

CSS实现垂直居中的五种方法

方法一 
        这个方法让一些<div>显示成table,然后我们就可以利用table的vertical-align属性了(vertical-align作用在其他一些元素上会表现得非常不一样(http://phrogz.net/CSS/vertical-align/index.html))。
Html代码  CSS实现垂直居中的五种方法
  1. <div id="wrapper">  
  2.     <div id="cell">  
  3.         <div class="content">Content goes here</div>  
  4.     </div>  
  5. </div>  
Css代码  CSS实现垂直居中的五种方法
  1. #wrapper {  
  2.     display: table;  
  3. }  
  4.   
  5. #cell {  
  6.     display: table-cell;  
  7.     vertical-align: middle;  
  8. }  
优点: 
1、内容可以动态地改变高度(不用在CSS里定义)。 
2、空间不够的话内容不会被截断。 
缺点: 
1、不支持IE(即使是IE8 beta)。 
2、多余的标签(没那么糟,看你自己怎么认为)。 

方法二 
        这个方法会用到一个top设为50%、margin-top设为内容高度的一半、绝对定位的div。这意味着它必须有一个固定的高度,这是在CSS里定义的。 
        因为它的高度固定,你可能想要给它设置overflow:auto;,这样如果内容太多的话就不会溢出而是会出现滚动条了。
Html代码  CSS实现垂直居中的五种方法
  1. <div id="content">Content goes here</div>  
Css代码  CSS实现垂直居中的五种方法
  1. #content {  
  2.     position: absolute;  
  3.     top: 50%;  
  4.     height: 240px;  
  5.     margin-top: -120px; /* negative half of the height */  
  6. }  
优点: 
1、支持所有的浏览器。 
2、不需要额外的标签。 
缺点: 
1、如果空间不够的话,内容就会消失(例如当div在body里面而用户缩小浏览器时,就不会出现滚动条)。 

方法三 
        在这个方法中,我们会在内容元素上方插入一个div,这个div会被设置成height:50%;margin-bottom:-contentheight/2,然后内容元素会因为清理浮动而居中了。
Html代码  CSS实现垂直居中的五种方法
  1. <div id="floater"></div>  
  2. <div id="content">Content here</div>  
Css代码  CSS实现垂直居中的五种方法
  1. #floater {  
  2.     float: left;  
  3.     height: 50%;  
  4.     margin-bottom: -120px;  
  5. }  
  6.   
  7. #content {  
  8.     clear: both;  
  9.     height: 240px;  
  10.     position: relative;  
  11. }  
优点: 
1、支持所有的浏览器。 
2、如果空间不够的话(例如缩小浏览器)就会出现滚动条,所以我们的内容不会被截断。 
缺点: 
1、我唯一能想到的就是需要一个额外的空元素(这其实没那么糟,看你自己怎么认为)。 

方法四 
        这个方式使用一个绝对定位且固定宽高的div,接着这个div被要求拉伸到top:0;bottom:0;,它因为高度被固定而做不到这一点,所以margin:auto;就让它居中了。这个方法类似于常见的使用margin:0 auto;来让块状元素水平居中。
Html代码  CSS实现垂直居中的五种方法
  1. <div id="content">Content here</div>  
Css代码  CSS实现垂直居中的五种方法
  1. #content {  
  2.     position: absolute;  
  3.     top: 0;  
  4.     bottom: 0;  
  5.     left: 0;  
  6.     right: 0;  
  7.     margin: auto;  
  8.     height: 240px;  
  9.     width: 70%;  
  10. }  
优点: 
1、简单。 
缺点: 
1、不支持IE(但支持IE8 beta)。 
2、空间不足的话内容会被截断,不会出现滚动条。 

方法五 
        这个方法只会居中一行文字。只需要设置line-height等于目标对象的高度,然后文字就居中了。
Html代码  CSS实现垂直居中的五种方法
  1. <div id="content">Content here</div>  
Css代码  CSS实现垂直居中的五种方法
  1. #content {  
  2.     height: 100px;  
  3.     line-height: 100px;  
  4. }  
优点: 
1、支持所有的浏览器。 
2、空间不足时不会被截断。 
缺点: 
1、只能用在文本上(不能用在块状元素上)。 
2、如果超过一行的话(例如换行)就失效了。 

这个方法在小元素上非常实用,例如居中一个按钮或单行文本输入框中的文本。 

选哪一种? 
        我个人最喜欢的是方法三--使用一个浮动元素然后清理浮动,它没什么大的缺点,因为内容元素设置了clear:both;,所以你还可以在它上面放其他元素,即使浏览器缩小居中的内容元素也不会盖住它们,请看示例(http://douglasheriot.com/tutorials/css_vertical_centre/demo5.html)
Html代码  CSS实现垂直居中的五种方法
  1. <div id="top">  
  2.     <h1>Title</h1>  
  3. </div>  
  4. <div id="floater"></div>  
  5. <div id="content">Content Here</div>  
Css代码  CSS实现垂直居中的五种方法
  1. #floater {  
  2.     float: left;  
  3.     height: 50%;  
  4.     margin-bottom: -120px;  
  5. }  
  6.   
  7. #top {  
  8.     float: right;  
  9.     width: 100%;  
  10.     text-align: center;  
  11. }  
  12.   
  13. #content {  
  14.     clear: both;  
  15.     height: 240px;  
  16.     position: relative;  
  17. }  
现在你知道它是如何工作的了,让我们开始创建一个简单好玩的网页!最后的成果看起来就像是这样: 

CSS实现垂直居中的五种方法
第一步 
        从语义标记入手是一个良好的习惯,这就是我们的页面结构:
	#floater (to push the content into the middle)
	#centred (the centre box)

		#side

			#logo
			#nav (unordered list <ul>)

		#content

	#bottom (for copyright, etc.)
这是我会使用到的xhtml代码:
Xhtml代码 
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  5. <title>A Centred Company</title>  
  6. <link rel="stylesheet" href="styles.css" type="text/css" media="all" />  
  7. </head>  
  8.   
  9. <body>  
  10.     <div id="floater"></div>  
  11.     <div id="centered">  
  12.   
  13.         <div id="side">  
  14.             <div id="logo">  
  15.                 <strong><span>A</span> Company</strong>  
  16.             </div>  
  17.             <ul id="nav">  
  18.                 <li><a href="#">Home</a></li>  
  19.                 <li><a href="#">Products</a></li>  
  20.                 <li><a href="#">Blog</a></li>  
  21.                 <li><a href="#">Contact</a></li>  
  22.                 <li><a href="#">About</a></li>  
  23.             </ul>  
  24.         </div>  
  25.   
  26.         <div id="content">  
  27.   
  28.             <h1>Page Title</h1>  
  29.   
  30.             <p>Holisticly re-engineer value-added outsourcing after  
  31.                 process-centric collaboration and idea-sharing. Energistically  
  32.                 simplify impactful niche markets via enabled imperatives. Holisticly  
  33.                 predominate premium innovation after compelling scenarios.  
  34.                 Seamlessly recaptiualize high standards in human capital with  
  35.                 leading-edge manufactured products. Distinctively syndicate  
  36.                 standards compliant schemas before robust vortals. Uniquely  
  37.                 recaptiualize leveraged web-readiness vis-a-vis out-of-the-box  
  38.                 information.</p>  
  39.   
  40.             <h2>Heading 2</h2>  
  41.   
  42.             <p>Efficiently embrace customized web-readiness rather than  
  43.                 customer directed processes. Assertively grow cross-platform  
  44.                 imperatives vis-a-vis proactive technologies. Conveniently empower  
  45.                 multidisciplinary meta-services without enterprise-wide interfaces.  
  46.                 Conveniently streamline competitive strategic theme areas with  
  47.                 focused e-markets. Phosfluorescently syndicate world-class  
  48.                 communities vis-a-vis value-added markets. Appropriately reinvent  
  49.                 holistic services before robust e-services.</p>  
  50.   
  51.         </div>  
  52.   
  53.     </div>  
  54.   
  55.     <div id="bottom">  
  56.         <p>Copyright notice goes here</p>  
  57.     </div>  
  58. </body>  
  59. </html>  

第二步 
        现在让我们从一些基本的CSS开始布局我们页面。你应该把它放在styles.css文件中,它已经在我们的html头部中引用过了。 
Css代码 
  1. html, body {  
  2.     margin: 0;  
  3.     padding: 0;  
  4.     height: 100%;  
  5. }  
  6.   
  7. body {  
  8.     background: url('page_bg.jpg'5050% no-repeat #FC3;  
  9.     font-family: Georgia, Times, serifs;  
  10. }  
  11.   
  12. #floater {  
  13.     position: relative;  
  14.     float: left;  
  15.     height: 50%;  
  16.     margin-bottom: -200px;  
  17.     width: 1px;  
  18. }  
  19.   
  20. #centered {  
  21.     position: relative;  
  22.     clear: left;  
  23.     height: 400px;  
  24.     width: 80%;  
  25.     max-width: 800px;  
  26.     min-width: 400px;  
  27.     margin: 0 auto;  
  28.     background: #fff;  
  29.     border: 4px solid #666;  
  30. }  
  31.   
  32. #bottom {  
  33.     position: absolute;  
  34.     bottom: 0;  
  35.     right: 0;  
  36. }  
  37.   
  38. #nav {  
  39.     position: absolute;  
  40.     left: 0;  
  41.     top: 0;  
  42.     bottom: 0;  
  43.     right: 70%;  
  44.     padding: 20px;  
  45.     margin: 10px;  
  46. }  
  47.   
  48. #content {  
  49.     position: absolute;  
  50.     left: 30%;  
  51.     right: 0;  
  52.     top: 0;  
  53.     bottom: 0;  
  54.     overflow: auto;  
  55.     height: 340px;  
  56.     padding: 20px;  
  57.     margin: 10px;  
  58. }  
        在让我们的内容垂直居中之前,body和html必须被拉伸到100%的高度。因为padding和margin是不计入高度的,所以我们要把它们设置为零,这样就不会因为margin出现滚动条了。 
        浮动元素的margin-bottom等于内容高度(400px)的一半,也就是200px。 
        你现在应该能看到这样的画面: 

CSS实现垂直居中的五种方法

        #centered的宽度是80%。这会让你的页面在小屏幕上小但是在大屏幕上宽(在我的中等大小的屏幕上,许多老网站很小而且会跑到左上角,这让我有一点烦)。这就是大家都知道的流式布局。设置min-width和max-width防止它太小或太大。虽然IE不支持最小和最大宽度。当然,你可以选择设置一个固定的宽度。 
        因为#centered设置了position:relative;,我们可以在它里面使用绝对定位来定位元素。#content使用了overflow:auto;,所以空间不足的时候会有滚动条出现。除非我们明确地指定了高度(不能只是指定了top和bottom,也不能是百分比),否则IE不认识overflow:auto;,所以我们也那样做了。 

第三步 
        最后一件事就是添加更多的样式来让它看起来更好看一点。让我们从菜单开始:
Css代码 
  1. #nav ul {  
  2.     list-style: none;  
  3.     padding: 0;  
  4.     margin: 20px 0 0 0;  
  5.     text-indent: 0;  
  6. }  
  7.   
  8. #nav li {  
  9.     padding: 0;  
  10.     margin: 3px;  
  11. }  
  12.   
  13. #nav li a {  
  14.     display: block;  
  15.     background-color: #e8e8e8;  
  16.     padding: 7px;  
  17.     margin: 0;  
  18.     text-decoration: none;  
  19.     color: #000;  
  20.     border-bottom: 1px solid #bbb;  
  21.     text-align: right;  
  22. }  
  23.   
  24. #nav li a::after {  
  25.     content: '»';  
  26.     color: #aaa;  
  27.     font-weight: bold;  
  28.     display: inline;  
  29.     float: right;  
  30.     margin: 0 2px 0 5px;  
  31. }  
  32.   
  33. #nav li a:hover, #nav li a:focus {  
  34.     background: #f8f8f8;  
  35.     border-bottom-color: #777;  
  36. }  
  37.   
  38. #nav li a:hover::after {  
  39.     margin: 0 0 0 7px;  
  40.     color: #f93;  
  41. }  
  42.   
  43. #nav li a:active {  
  44.     padding: 8px 7px 6px 7px;  
  45. }  
        让一个列表变成一个菜单要做的第一件事就是设置list-sytle:none来去掉圆点,然后去掉所有的margin和padding。如果你要让它有margin或padding的话就要明确地指定出来,不要依赖浏览器的默认样式,因为不同浏览器之间的差别太大了。 
        下一件需要注意的事就是所有的链接都被设置成了块状元素。这让它们填充了整行的空间,也给了你更多的控制。如果你想让你的菜单水平排列的话(在我们的设计中不管用),你也可以让它们浮动起来。 
        另外一件关于菜单值得关注的有趣的事儿就是:before和:after伪元素能够让你在元素的前后插入一些内容。这是一个添加小图标或字符的好方法,例如每一个链接末尾的箭头。尽管这种方法不支持8以前的IE版本。 

CSS实现垂直居中的五种方法

第四步 
        最后一件要做的事就是再添加一些样式来让页面变得更好看。
Css代码 
  1. #centered {  
  2.     -webkit-border-radius: 8px;  
  3.     -moz-border-radius: 8px;  
  4.     border-radius: 8px;  
  5. }  
  6.   
  7. h1, h2, h3, h4, h5, h6 {  
  8.     font-family: Helvetica, Arial, sans-serif;  
  9.     font-weight: normal;  
  10.     color: #666;  
  11. }  
  12.   
  13. h1 {  
  14.     color: #f93;  
  15.     border-bottom: 1px solid #ddd;  
  16.     letter-spacing: -0.05em;  
  17.     font-weight: bold;  
  18.     margin-top: 0;  
  19.     padding-top: 0;  
  20. }  
  21.   
  22. #bottom {  
  23.     padding: 10px;  
  24.     font-size: 0.7em;  
  25.     color: #f03;  
  26. }  
  27.   
  28. #logo {  
  29.     font-size: 2em;  
  30.     text-align: center;  
  31.     color: #999;  
  32. }  
  33.   
  34. #logo strong {  
  35.     font-weight: normal;  
  36. }  
  37.   
  38. #logo span {  
  39.     display: block;  
  40.     font-size: 4em;  
  41.     line-height: 0.7em;  
  42.     color: #666;  
  43. }  
  44.   
  45. p, h2, h3 {  
  46.     line-height: 1.6em;  
  47. }  
  48.   
  49. a {  
  50.     color: #f03;  
  51. }  
        要注意的一点就是#centered上的圆角。在CSS3中有一个border-radius属性来设置圆角的弧度。这还没有被任何一个主流浏览器实现,除非你使用-moz或-webkit前缀(分别对应Mozilla Firefox和Safari/Webkit)

CSS实现垂直居中的五种方法 

兼容性 
        就像你猜想的那样,IE是唯一一个给你带来麻烦的主流浏览器: 
               * #floater必须定义一个宽度,否则它在任何版本的IE中都不起作用 
               * IE6在我们的菜单周围加入了太多的空白,这破坏了我们的菜单 

起因 
        我不是自己一个人发现所有这些方法的。这里是一些我看过的描述这些技术的文章(如果你感兴趣的话,我推荐你不妨读一下): 
Understanding vertical-align, or "How (Not) To Vertically Center Content" 
Vertical centering using CSS 
Vertical Centering in CSS