CSS实现垂直居中的五种方法
CSS有许多方法可以实现垂直居中,但是选择合适的方法却很难。我将为你展示我见过的所有的最棒的方法以及如何创建一个精致小巧的居中网页。
使用CSS实现垂直居中并不是一件容易的事,有许多不同的方法,其中一些可能在某些浏览器中不生效。让我们来看看五种不同的垂直居中的方法和它们各自的优缺点(你可以看看我的测试页面(http://douglasheriot.com/tutorials/css_vertical_centre/demo4.html),它简明扼要地解释了所有这些方法)。
方法一
这个方法让一些<div>显示成table,然后我们就可以利用table的vertical-align属性了(vertical-align作用在其他一些元素上会表现得非常不一样(http://phrogz.net/CSS/vertical-align/index.html))。
优点:
1、内容可以动态地改变高度(不用在CSS里定义)。
2、空间不够的话内容不会被截断。
缺点:
1、不支持IE(即使是IE8 beta)。
2、多余的标签(没那么糟,看你自己怎么认为)。
方法二
这个方法会用到一个top设为50%、margin-top设为内容高度的一半、绝对定位的div。这意味着它必须有一个固定的高度,这是在CSS里定义的。
因为它的高度固定,你可能想要给它设置overflow:auto;,这样如果内容太多的话就不会溢出而是会出现滚动条了。
优点:
1、支持所有的浏览器。
2、不需要额外的标签。
缺点:
1、如果空间不够的话,内容就会消失(例如当div在body里面而用户缩小浏览器时,就不会出现滚动条)。
方法三
在这个方法中,我们会在内容元素上方插入一个div,这个div会被设置成height:50%;margin-bottom:-contentheight/2,然后内容元素会因为清理浮动而居中了。
优点:
1、支持所有的浏览器。
2、如果空间不够的话(例如缩小浏览器)就会出现滚动条,所以我们的内容不会被截断。
缺点:
1、我唯一能想到的就是需要一个额外的空元素(这其实没那么糟,看你自己怎么认为)。
方法四
这个方式使用一个绝对定位且固定宽高的div,接着这个div被要求拉伸到top:0;bottom:0;,它因为高度被固定而做不到这一点,所以margin:auto;就让它居中了。这个方法类似于常见的使用margin:0 auto;来让块状元素水平居中。
优点:
1、简单。
缺点:
1、不支持IE(但支持IE8 beta)。
2、空间不足的话内容会被截断,不会出现滚动条。
方法五
这个方法只会居中一行文字。只需要设置line-height等于目标对象的高度,然后文字就居中了。
优点:
1、支持所有的浏览器。
2、空间不足时不会被截断。
缺点:
1、只能用在文本上(不能用在块状元素上)。
2、如果超过一行的话(例如换行)就失效了。
这个方法在小元素上非常实用,例如居中一个按钮或单行文本输入框中的文本。
选哪一种?
我个人最喜欢的是方法三--使用一个浮动元素然后清理浮动,它没什么大的缺点,因为内容元素设置了clear:both;,所以你还可以在它上面放其他元素,即使浏览器缩小居中的内容元素也不会盖住它们,请看示例(http://douglasheriot.com/tutorials/css_vertical_centre/demo5.html)
现在你知道它是如何工作的了,让我们开始创建一个简单好玩的网页!最后的成果看起来就像是这样:
第一步
从语义标记入手是一个良好的习惯,这就是我们的页面结构:
第二步
现在让我们从一些基本的CSS开始布局我们页面。你应该把它放在styles.css文件中,它已经在我们的html头部中引用过了。
在让我们的内容垂直居中之前,body和html必须被拉伸到100%的高度。因为padding和margin是不计入高度的,所以我们要把它们设置为零,这样就不会因为margin出现滚动条了。
浮动元素的margin-bottom等于内容高度(400px)的一半,也就是200px。
你现在应该能看到这样的画面:
#centered的宽度是80%。这会让你的页面在小屏幕上小但是在大屏幕上宽(在我的中等大小的屏幕上,许多老网站很小而且会跑到左上角,这让我有一点烦)。这就是大家都知道的流式布局。设置min-width和max-width防止它太小或太大。虽然IE不支持最小和最大宽度。当然,你可以选择设置一个固定的宽度。
因为#centered设置了position:relative;,我们可以在它里面使用绝对定位来定位元素。#content使用了overflow:auto;,所以空间不足的时候会有滚动条出现。除非我们明确地指定了高度(不能只是指定了top和bottom,也不能是百分比),否则IE不认识overflow:auto;,所以我们也那样做了。
第三步
最后一件事就是添加更多的样式来让它看起来更好看一点。让我们从菜单开始:
让一个列表变成一个菜单要做的第一件事就是设置list-sytle:none来去掉圆点,然后去掉所有的margin和padding。如果你要让它有margin或padding的话就要明确地指定出来,不要依赖浏览器的默认样式,因为不同浏览器之间的差别太大了。
下一件需要注意的事就是所有的链接都被设置成了块状元素。这让它们填充了整行的空间,也给了你更多的控制。如果你想让你的菜单水平排列的话(在我们的设计中不管用),你也可以让它们浮动起来。
另外一件关于菜单值得关注的有趣的事儿就是:before和:after伪元素能够让你在元素的前后插入一些内容。这是一个添加小图标或字符的好方法,例如每一个链接末尾的箭头。尽管这种方法不支持8以前的IE版本。
第四步
最后一件要做的事就是再添加一些样式来让页面变得更好看。
要注意的一点就是#centered上的圆角。在CSS3中有一个border-radius属性来设置圆角的弧度。这还没有被任何一个主流浏览器实现,除非你使用-moz或-webkit前缀(分别对应Mozilla Firefox和Safari/Webkit)
兼容性
就像你猜想的那样,IE是唯一一个给你带来麻烦的主流浏览器:
* #floater必须定义一个宽度,否则它在任何版本的IE中都不起作用
* IE6在我们的菜单周围加入了太多的空白,这破坏了我们的菜单
起因
我不是自己一个人发现所有这些方法的。这里是一些我看过的描述这些技术的文章(如果你感兴趣的话,我推荐你不妨读一下):
Understanding vertical-align, or "How (Not) To Vertically Center Content"
Vertical centering using CSS
Vertical Centering in CSS
使用CSS实现垂直居中并不是一件容易的事,有许多不同的方法,其中一些可能在某些浏览器中不生效。让我们来看看五种不同的垂直居中的方法和它们各自的优缺点(你可以看看我的测试页面(http://douglasheriot.com/tutorials/css_vertical_centre/demo4.html),它简明扼要地解释了所有这些方法)。
方法一
这个方法让一些<div>显示成table,然后我们就可以利用table的vertical-align属性了(vertical-align作用在其他一些元素上会表现得非常不一样(http://phrogz.net/CSS/vertical-align/index.html))。
- <div id="wrapper">
- <div id="cell">
- <div class="content">Content goes here</div>
- </div>
- </div>
- #wrapper {
- display: table;
- }
- #cell {
- display: table-cell;
- vertical-align: middle;
- }
1、内容可以动态地改变高度(不用在CSS里定义)。
2、空间不够的话内容不会被截断。
缺点:
1、不支持IE(即使是IE8 beta)。
2、多余的标签(没那么糟,看你自己怎么认为)。
方法二
这个方法会用到一个top设为50%、margin-top设为内容高度的一半、绝对定位的div。这意味着它必须有一个固定的高度,这是在CSS里定义的。
因为它的高度固定,你可能想要给它设置overflow:auto;,这样如果内容太多的话就不会溢出而是会出现滚动条了。
- <div id="content">Content goes here</div>
- #content {
- position: absolute;
- top: 50%;
- height: 240px;
- margin-top: -120px; /* negative half of the height */
- }
1、支持所有的浏览器。
2、不需要额外的标签。
缺点:
1、如果空间不够的话,内容就会消失(例如当div在body里面而用户缩小浏览器时,就不会出现滚动条)。
方法三
在这个方法中,我们会在内容元素上方插入一个div,这个div会被设置成height:50%;margin-bottom:-contentheight/2,然后内容元素会因为清理浮动而居中了。
- <div id="floater"></div>
- <div id="content">Content here</div>
- #floater {
- float: left;
- height: 50%;
- margin-bottom: -120px;
- }
- #content {
- clear: both;
- height: 240px;
- position: relative;
- }
1、支持所有的浏览器。
2、如果空间不够的话(例如缩小浏览器)就会出现滚动条,所以我们的内容不会被截断。
缺点:
1、我唯一能想到的就是需要一个额外的空元素(这其实没那么糟,看你自己怎么认为)。
方法四
这个方式使用一个绝对定位且固定宽高的div,接着这个div被要求拉伸到top:0;bottom:0;,它因为高度被固定而做不到这一点,所以margin:auto;就让它居中了。这个方法类似于常见的使用margin:0 auto;来让块状元素水平居中。
- <div id="content">Content here</div>
- #content {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- margin: auto;
- height: 240px;
- width: 70%;
- }
1、简单。
缺点:
1、不支持IE(但支持IE8 beta)。
2、空间不足的话内容会被截断,不会出现滚动条。
方法五
这个方法只会居中一行文字。只需要设置line-height等于目标对象的高度,然后文字就居中了。
- <div id="content">Content here</div>
- #content {
- height: 100px;
- line-height: 100px;
- }
1、支持所有的浏览器。
2、空间不足时不会被截断。
缺点:
1、只能用在文本上(不能用在块状元素上)。
2、如果超过一行的话(例如换行)就失效了。
这个方法在小元素上非常实用,例如居中一个按钮或单行文本输入框中的文本。
选哪一种?
我个人最喜欢的是方法三--使用一个浮动元素然后清理浮动,它没什么大的缺点,因为内容元素设置了clear:both;,所以你还可以在它上面放其他元素,即使浏览器缩小居中的内容元素也不会盖住它们,请看示例(http://douglasheriot.com/tutorials/css_vertical_centre/demo5.html)
- <div id="top">
- <h1>Title</h1>
- </div>
- <div id="floater"></div>
- <div id="content">Content Here</div>
- #floater {
- float: left;
- height: 50%;
- margin-bottom: -120px;
- }
- #top {
- float: right;
- width: 100%;
- text-align: center;
- }
- #content {
- clear: both;
- height: 240px;
- position: relative;
- }
从语义标记入手是一个良好的习惯,这就是我们的页面结构:
#floater (to push the content into the middle) #centred (the centre box) #side #logo #nav (unordered list <ul>) #content #bottom (for copyright, etc.)这是我会使用到的xhtml代码:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title>A Centred Company</title>
- <link rel="stylesheet" href="styles.css" type="text/css" media="all" />
- </head>
- <body>
- <div id="floater"></div>
- <div id="centered">
- <div id="side">
- <div id="logo">
- <strong><span>A</span> Company</strong>
- </div>
- <ul id="nav">
- <li><a href="#">Home</a></li>
- <li><a href="#">Products</a></li>
- <li><a href="#">Blog</a></li>
- <li><a href="#">Contact</a></li>
- <li><a href="#">About</a></li>
- </ul>
- </div>
- <div id="content">
- <h1>Page Title</h1>
- <p>Holisticly re-engineer value-added outsourcing after
- process-centric collaboration and idea-sharing. Energistically
- simplify impactful niche markets via enabled imperatives. Holisticly
- predominate premium innovation after compelling scenarios.
- Seamlessly recaptiualize high standards in human capital with
- leading-edge manufactured products. Distinctively syndicate
- standards compliant schemas before robust vortals. Uniquely
- recaptiualize leveraged web-readiness vis-a-vis out-of-the-box
- information.</p>
- <h2>Heading 2</h2>
- <p>Efficiently embrace customized web-readiness rather than
- customer directed processes. Assertively grow cross-platform
- imperatives vis-a-vis proactive technologies. Conveniently empower
- multidisciplinary meta-services without enterprise-wide interfaces.
- Conveniently streamline competitive strategic theme areas with
- focused e-markets. Phosfluorescently syndicate world-class
- communities vis-a-vis value-added markets. Appropriately reinvent
- holistic services before robust e-services.</p>
- </div>
- </div>
- <div id="bottom">
- <p>Copyright notice goes here</p>
- </div>
- </body>
- </html>
第二步
现在让我们从一些基本的CSS开始布局我们页面。你应该把它放在styles.css文件中,它已经在我们的html头部中引用过了。
- html, body {
- margin: 0;
- padding: 0;
- height: 100%;
- }
- body {
- background: url('page_bg.jpg') 50% 50% no-repeat #FC3;
- font-family: Georgia, Times, serifs;
- }
- #floater {
- position: relative;
- float: left;
- height: 50%;
- margin-bottom: -200px;
- width: 1px;
- }
- #centered {
- position: relative;
- clear: left;
- height: 400px;
- width: 80%;
- max-width: 800px;
- min-width: 400px;
- margin: 0 auto;
- background: #fff;
- border: 4px solid #666;
- }
- #bottom {
- position: absolute;
- bottom: 0;
- right: 0;
- }
- #nav {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- right: 70%;
- padding: 20px;
- margin: 10px;
- }
- #content {
- position: absolute;
- left: 30%;
- right: 0;
- top: 0;
- bottom: 0;
- overflow: auto;
- height: 340px;
- padding: 20px;
- margin: 10px;
- }
浮动元素的margin-bottom等于内容高度(400px)的一半,也就是200px。
你现在应该能看到这样的画面:
#centered的宽度是80%。这会让你的页面在小屏幕上小但是在大屏幕上宽(在我的中等大小的屏幕上,许多老网站很小而且会跑到左上角,这让我有一点烦)。这就是大家都知道的流式布局。设置min-width和max-width防止它太小或太大。虽然IE不支持最小和最大宽度。当然,你可以选择设置一个固定的宽度。
因为#centered设置了position:relative;,我们可以在它里面使用绝对定位来定位元素。#content使用了overflow:auto;,所以空间不足的时候会有滚动条出现。除非我们明确地指定了高度(不能只是指定了top和bottom,也不能是百分比),否则IE不认识overflow:auto;,所以我们也那样做了。
第三步
最后一件事就是添加更多的样式来让它看起来更好看一点。让我们从菜单开始:
- #nav ul {
- list-style: none;
- padding: 0;
- margin: 20px 0 0 0;
- text-indent: 0;
- }
- #nav li {
- padding: 0;
- margin: 3px;
- }
- #nav li a {
- display: block;
- background-color: #e8e8e8;
- padding: 7px;
- margin: 0;
- text-decoration: none;
- color: #000;
- border-bottom: 1px solid #bbb;
- text-align: right;
- }
- #nav li a::after {
- content: '»';
- color: #aaa;
- font-weight: bold;
- display: inline;
- float: right;
- margin: 0 2px 0 5px;
- }
- #nav li a:hover, #nav li a:focus {
- background: #f8f8f8;
- border-bottom-color: #777;
- }
- #nav li a:hover::after {
- margin: 0 0 0 7px;
- color: #f93;
- }
- #nav li a:active {
- padding: 8px 7px 6px 7px;
- }
下一件需要注意的事就是所有的链接都被设置成了块状元素。这让它们填充了整行的空间,也给了你更多的控制。如果你想让你的菜单水平排列的话(在我们的设计中不管用),你也可以让它们浮动起来。
另外一件关于菜单值得关注的有趣的事儿就是:before和:after伪元素能够让你在元素的前后插入一些内容。这是一个添加小图标或字符的好方法,例如每一个链接末尾的箭头。尽管这种方法不支持8以前的IE版本。
第四步
最后一件要做的事就是再添加一些样式来让页面变得更好看。
- #centered {
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
- }
- h1, h2, h3, h4, h5, h6 {
- font-family: Helvetica, Arial, sans-serif;
- font-weight: normal;
- color: #666;
- }
- h1 {
- color: #f93;
- border-bottom: 1px solid #ddd;
- letter-spacing: -0.05em;
- font-weight: bold;
- margin-top: 0;
- padding-top: 0;
- }
- #bottom {
- padding: 10px;
- font-size: 0.7em;
- color: #f03;
- }
- #logo {
- font-size: 2em;
- text-align: center;
- color: #999;
- }
- #logo strong {
- font-weight: normal;
- }
- #logo span {
- display: block;
- font-size: 4em;
- line-height: 0.7em;
- color: #666;
- }
- p, h2, h3 {
- line-height: 1.6em;
- }
- a {
- color: #f03;
- }
兼容性
就像你猜想的那样,IE是唯一一个给你带来麻烦的主流浏览器:
* #floater必须定义一个宽度,否则它在任何版本的IE中都不起作用
* IE6在我们的菜单周围加入了太多的空白,这破坏了我们的菜单
起因
我不是自己一个人发现所有这些方法的。这里是一些我看过的描述这些技术的文章(如果你感兴趣的话,我推荐你不妨读一下):
Understanding vertical-align, or "How (Not) To Vertically Center Content"
Vertical centering using CSS
Vertical Centering in CSS