分享
 
 
 

CSS实现完美垂直居中

王朝html/css/js·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

之前看到很多人一直都问这个问题,不过当时我没当一回事,因为在 CSS 中要垂直居中,多数是在有高度的情况下,或者容器高度不定的情况下才用,看上去比较舒服,而且实现的方法也不少,不一定要拘泥于和 table 布局一样。不过最近有人问了几个例子,看来对此的需求还不少。现在就把我经验拿出来分享一下,希望大家鼓鼓掌。

首先,要有一个概念:凡是 table 布局可以实现的,CSS 一定可以实现。CSS 可以实现的,table 未必能做到。

现在来几个例子:

一、单行内容的居中

只考虑单行是最简单的,无论是否给容器固定高度,只要给容器设置 line-height 和 height,并使两值相等,再加上 over-flow: hidden 就可以了.middle-demo-1{

height: 4em;

line-height: 4em;

overflow: hidden;

}

优点:

1. 同时支持块级和内联极元素

2. 支持所有浏览器

缺点:

1. 只能显示一行

2. IE中不支持<img>等的居中

要注意的是:

1. 使用相对高度定义你的 height 和 line-height

2. 不想毁了你的布局的话,overflow: hidden 一定要

为什么?

请比较以下两个例子:<p style="background: #900; color: #00f; font: bold 12px/24px Helvertica,Arial,sans-serif; height:24px; width:370px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p> <br/> <br/> <p style="background: #090; color: #00f; font: bold 12px/2em Helvertica,Arial,sans-serif; height:2em; width:370px; overflow: hidden;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]

上一个高度是用的绝对单位px,并且没有隐藏溢出,下一个高度用的单位是相对单位em,并且隐藏了溢出。如果你的浏览器支持放大字体,那么尽情地放大字体,看看会出现什么效果。

二、多行内容居中,且容器高度可变

也很简单,给出一致的 padding-bottom 和 padding-top 就行.middle-demo-2{

padding-top: 24px;

padding-bottom: 24px;

}

优点:

1. 同时支持块级和内联极元素

2. 支持非文本内容

3. 支持所有浏览器

缺点:

容器不能固定高度

三、把容器当作表格单元

CSS 提供一系列diplay属性值,包括 display: table, display: table-row, display: table-cell 等,能把元素当作表格单元来显示。这是再加上 vertical-align: middle, 就和表格中的 valign="center" 一样了。.middle-demo-3{

display: table-cell;

height: 300px;

vertical-align: middle;

}

可惜IE不支持这些属性,不过在其他浏览器上显示效果非常完美。

要注意的是:和一个合法的<td>元素必须在<table>里一样,display: table-cell 元素必须作为 display: table 的元素的子孙出现。

优点:

不用说了吧,就是表格,效果和表格一模一样

缺点:

IE下无效

四、以毒攻毒!用 IE 的 bug 解决 IE 中的绝对居中

先不得不说一句,IE 真的是个很烂的浏览器,CSS1中的定义都不支持,害得要我们转个大圈子来造居中。不过就像我说的,凡是 table 布局可以实现的,CSS 一定可以实现,即使在 IE 里也不例外。我研究 IE layout 模式多年,还是找出了一个可以在 IE 中绝对居中的方法。这个方法就是基于 IE layout 的 bug,也可以算以毒攻毒。至于原理,不要问我,这是独门秘学,何况三言两语也讲不清楚,只要好用就行.middle-demo-4{

height: 300px;

position: relative;

}

.middle-demo-4 div{

position: absolute;

top: 50%;

left: 0;

}

.middle-demo-4 div div{

position: relative;

top: -50%;

left: 0;

}

五、整合三和四,写出支持所有浏览器的垂直居中容器!

思路是利用 IE 和 非IE 浏览器的 CSS hack, 整合三和四的CSS,写出兼容主流浏览器的垂直居中容器。具体代码就不给出了,大家权当作练习练习。例子可以在下面的附录中找到。

最终实测支持的浏览器:IE6+, Mozilla 1.7, Netscape Navigator 8, Opera 8.0+, Firefox 1.0+ 和 Safari 1.0+IE5 下需要加上对合适模型的补正。

推测支持的浏览器:Mozilla 1.5+, Netscape Navigator 7+, Opera 7+

未测试浏览器:Konqueror

最后附上自己写的,所有居中布局的范例网页,大家不明白可以参考。<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Demo:: vertical align: middle</title>

<meta lang="en" name="author" content="Spenser Lee" />

<meta lang="en" name="copyright" content="(c)2006 Liberty Studio" />

<style media="screen" type="text/css">

html,body,div,h1,h2,pre,dd,ol{margin: 0;padding: 0;border: 0}

html{min-width: 779px}

body{background: #fff;color: #596480;text-align: center}

div#main-wrapper{padding: 12px 5px;width: 769px;margin: 0 auto}

div,code,p,h1,h2,address,dt,dd,li{font: normal 12px/1.5em Tahoma,"Lucida Grande",Helvetica,Verdana,Lucida,Arial,"Arial Unicode",sans-serif,serif}

h1{font-size: 22px;font-weight: bold;border-left: 12px solid #324f96;background: #e0eaf4;color: #4868a9;height: 4em;line-height: 4em;padding: 0 12px;overflow: hidden; text-align: left}

h2{font-size: 12px;font-weight: bold;background: #c0014e;color: #fff;height: 2.5em;line-height: 2.5em;padding: 0 24px;overflow: hidden;margin: 12px 0;text-align: left}

h2 a{color: #fff;background: transparent}

h2 a:hover{text-decoration: none}

p{margin: 6px 0;padding: 0 12px 0 24px;text-indent: 2em;text-align: left}

p.snap-back{text-align: right}

code{display: block;font-family: "Courier New", Courier, monospace, mono, serif;margin: 12px auto;padding: 12px;border: 1px solid #596480;color: inherit;background: #f6f6f6;text-align: left;white-space: pre;width: 350px}

strong{font-weight: bold}

em{font-style: italic}

address{display: block;padding: 0 12px;margin: 12px 0;text-align: right}

dl{margin: 6px 0;padding: 0 12px 0 24px;text-align: left}

dt{margin: 0;text-indent: 2em;font-weight: bold}

dd{margin-left: 24px;text-indent: 2em}

li{list-style: square inside none;text-align: left}

ol#table-of-content{padding-left: 24px}

a{color: #c0014e;background: transparent;text-decoration: none}

a:hover{text-decoration: underline}

div.demo{width: 400px;margin: 12px auto;border: 1px solid #596480;color: inherit;background: #ffc}

div.demo p{text-align: left;margin: 24px;text-indent: 0}

p#demo-1{margin: 12px auto;padding: 0 12px;width: 400px;text-indent: 0;border: 1px solid #596480;color: inherit;background: #ffc;line-height: 4em;height: 4em;overflow: hidden}

div#demo-2{padding: 50px 0}

div#demo-4, div#demo-5{height: 300px;position: relative}

div#demo-4 div, div#demo-5 div{position: absolute;top: 50%;left: 0}

div#demo-4 p, div#demo-5 p{position: relative;top: -50%}

div#demo-3{display: table;height: 300px;border-collapse: collapse}

div#main-wrapper>div#demo-5{position: static;display:table}

div#main-wrapper>div#demo-5>div{display:table-cell;vertical-align:middle;position:static}

div#demo-3>div{display: table-row}

div#demo-3>div>div{display: table-cell;vertical-align: middle}

span.property{font-family: "Courier New", Courier, monospace, mono, serif;border-bottom: 1px dotted #596480;background: #ffc;color: #c0014e}

p.copyright{line-height: 3em;text-align: center;border-top: 1px dotted #596480}

</style>

</head>

<body>

<div id="main-wrapper">

<h1>Demo of middled vertical align</h1>

<address>

Author: Spenser Lee, Liberty Studio<br />

Originally posted on <a href="http://www.blueidea.com/bbs/" title="BlueIdea Forum">BlueIdea Forum</a>

</address>

<h2><a id="bullet-0">Table of centents:</a></h2>

<ol id="table-of-content">

<li><a href="#bullet-1" title="Single line countainer with/without a fixed height">Single line countainer with/without a fixed height</a></li>

<li><a href="#bullet-2" title="Align multi-line container which does not have a fixed height">Align multi-line container which does not have a fixed height</a></li>

<li><a href="#bullet-3" title="Simulating table layout in container with a fixed height">Simulating table layout in container with a fixed height</a></li>

<li><a href="#bullet-4" title="IE's solution">IE's solution</a></li>

<li><a href="#bullet-5" title="A perfect compounded sample">A perfect compounded sample</a></li>

</ol>

<h2><a id="bullet-1">Case One: Single line countainer with/without a fixed height</a></h2>

<p>If you only want to display a container which only holds a single line of text, you can set <span class="property">line-height</span> property to <span class="property">height</span> property, then set <span class="property">overflow</span> to hidden.</p>

<p><strong>Sample:</strong></p>

<p id="demo-1">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>

<p><strong>Core code:</strong></p>

<pre><code>.middle-demo-1{

height: 4em;

line-height: 4em;

overflow: hidden;

}</code></pre>

<dl>

<dt>Notes:</dt>

<dd>

<ol>

<li>I strongly recommend you use relative size in <span class="property">height</span> and <span class="property">line-height</span> property. <em>Why?</em> You can simply set the font size larger if your browser support it. When it gets large enough, you will see the countainer is stretched and the <span class="property">height</span> is no longer equal to <span class="property">line-height</span> property, thus, the layout is messed up. Using relative size as <span class="property">em, ex</span> or <span class="property">%</span> will let your countainer stretch with the content.</li>

<li><span class="property">overflow: hidden</span> is a must. <em>Why?</em> Same as above. Just ensure <span class="property">height</span> and <span class="property">line-height</span> are always equal.</li>

</ol>

</dd>

</dl>

<dl>

<dt>Pros:</dt>

<dd>

<ol>

<li>Fits in both <span class="property">block</span> elements and <span class="property">inline</span> elements.</li>

<li>Capable of all 5th-gen browsers.</li>

</ol>

</dd>

</dl>

<dl>

<dt>Cons:</dt>

<dd>

<ol>

<li>Text length is limited. Max with only <em>one</em> line.</li>

<li>Does not work well on none text contents such as images and objects.</li>

</ol>

</dd>

</dl>

<p class="snap-back"><a href="#bullet-0" title="Back top table of centents">Back</a></p>

<h2><a id="bullet-2">Case Two: Align multi-line container which does not have a fixed height</a></h2>

<p>In this case, we should simply set a pair of fixed equivalences to padding-top and padding-bottom attribute. It works on both IE and non-IE browsers.</p>

<p><strong>Sample:</strong></p>

<div class="demo" id="demo-2">

<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas dignissim diam eu sem. Proin nunc ante, accumsan sollicitudin, sodales at, semper sed, ipsum. Etiam orci. Vestibulum magna lectus, venenatis nec, tempus ac, dictum vel, lorem.</p>

</div>

<p><strong>Core code:</strong></p>

<pre><code>.middle-demo-2{

padding-top: 24px;

padding-bottom: 24px;

}</code></pre>

<dl>

<dt>Pros:</dt>

<dd>

<ol>

<li>Fits in both <span class="property">block</span> elements and <span class="property">inline</span> elements.</li>

<li>Works on none text contents as fine as text contents.</li>

<li>Capable of all 5th-gen browsers. Might need a little tune-up for the box model bug of IE5 though.</li>

</ol>

</dd>

</dl>

<dl>

<dt>Cons:</dt>

<dd>

<ol>

<li>You can <em>not</em> assign height in this solution.</li>

</ol>

</dd>

</dl>

<p class="snap-back"><a href="#bullet-0" title="Back top table of centents">Back</a></p>

<h2><a id="bullet-3">Case Three: Simulating table layout in container with a fixed height</a></h2>

<p>CSS offers a set of very convenient display atrribute values called <span class="property">display: table</span>, <span class="property">display: table-row</span>, <span class="property">display: table-cell</span> and other display values begin with <span class="property">table-</span>. It offers a way to simulate table layout in all elements. As a result, any element with <span class="property">display: table-cell</span>, <span class="property">vertical-align: middle</span> and a fixed height will display exactly like a table cell.</p>

<p><strong>Sample:</strong> (You may not be able to view the effect on IE)</p>

<div class="demo" id="demo-3">

<div><div><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas dignissim diam eu sem. Proin nunc ante, accumsan sollicitudin, sodales at, semper sed, ipsum. Etiam orci. Vestibulum magna lectus, venenatis nec, tempus ac, dictum vel, lorem.</p></div></div>

</div>

<p><strong>Core code:</strong></p>

<pre><code>.middle-demo-3{

display: table-cell;

height: 300px;

vertical-align: middle;

}</code></pre>

<dl>

<dt>Notes:</dt>

<dd>

<ol>

<li><span class="property">display: table-cell</span> must work with other elements with <span class="property">display: table</span> value sets in order to form a literal table. Or it might cause unexceptable bugs.</li>

<li>Sadly IE series (including the latest IE 7 beta) does not support any of <span class="property">display: table</span> values, so it won't work in IE.</li>

</ol>

</dd>

</dl>

<dl>

<dt>Pros:</dt>

<dd>

<ol>

<li>It has the most perfect render for <span class="property">vertical-align: middle</span> align.</li>

</ol>

</dd>

</dl>

<dl>

<dt>Cons:</dt>

<dd>

<ol>

<li>It only works in latest versions of non-IE browsers, such as Mozilla, Firefox, Netscape 8, Opera 8, and Safari.</li>

</ol>

</dd>

</dl>

<p class="snap-back"><a href="#bullet-0" title="Back top table of centents">Back</a></p>

<h2><a id="bullet-4">Case Four: IE's solution</a></h2>

<p>Since IE is a lame browser when it comes to ANYTHING, so you can't use the solution above simply because IE does not recognize it at all. However, <strong>there has been nothing yet you can not code with CSS if you have already coded it with table</strong>. It even offers you possibility to layout your page that tables can not do!</p>

<p>So what's the solution for IE? Like what we always do: Hit IE's back with the BUGS it offers!</p>

<p><strong>Sample:</strong> (You are able to view the correct result only on IE)</p>

<div class="demo" id="demo-4">

<div><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas dignissim diam eu sem. Proin nunc ante, accumsan sollicitudin, sodales at, semper sed, ipsum. Etiam orci. Vestibulum magna lectus, venenatis nec, tempus ac, dictum vel, lorem.</p></div>

</div>

<pre><code>.middle-demo-4{

height: 300px;

position: relative;

}

.middle-demo-4 div{

position: absolute;

top: 50%;

left: 0;

}

.middle-demo-4 div div{

position: relative;

top: -50%;

left: 0;

}</code></pre>

<p>See? Don't ask me why it worked. This hack is based on years of study in IE's own stupid layout model and it works very well, even in IE5 given the box width hack. I won't tell you the theory behind all these. It's my top secret, with which I solved a lot of other cross browser layout problems, and I'm not going to share it with you. But you are free to use this IE hack It's kinda handful in most occassions.</p>

<dl>

<dt>Pros:</dt>

<dd>

<ol>

<li>The only perfect vertical align method in IE. It works even better then add automatic <span class="property">padding</span>s.</li>

</ol>

</dd>

</dl>

<dl>

<dt>Cons:</dt>

<dd>

<ol>

<li>After all it's a CSS hack. We can avoid it if not for IE.</li>

</ol>

</dd>

</dl>

<p class="snap-back"><a href="#bullet-0" title="Back top table of centents">Back</a></p>

<h2><a id="bullet-5">Case Five: A perfect compounded sample</a></h2>

<p>Here's the perfect compounded solution on vertical centering that works on almost all latest browsers.</p>

<p><strong>Sample:</strong> (This works on almost all browsers)</p>

<div class="demo" id="demo-5">

<div><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas dignissim diam eu sem. Proin nunc ante, accumsan sollicitudin, sodales at, semper sed, ipsum. Etiam orci. Vestibulum magna lectus, venenatis nec, tempus ac, dictum vel, lorem.</p></div>

</div>

<p>I'm not going to give you the full code of this one. But it's not difficult to write it yourself, with the solution of case 3 and 4, and a little knowledge in IE/non-IE CSS hackers. And actually the hacking style is not limited, so I don't want to force you to use my hacking style neither. Stop being lazy, and write the code yourself!</p>

<dl>

<dt>Browser capability:</dt>

<dd>

<ol>

<li>Works on: IE6+, Mozilla 1.5+, Netscape Navigator 7+, Opera 7+, Firefox 1.0+ and Safari 1.0+</li>

<li>On IE5, you might need to apply the box model hacker to make the height correct.</li>

<li>Untested: WebOmini, Konqueror.</li>

<li>Fails on: Other browsers not reffered in the list above.</li>

</ol>

</dd>

</dl>

<p class="snap-back"><a href="#bullet-0" title="Back top table of centents">Back</a></p>

<p class="copyright">Copyright &copy; Spenser Lee, 2006 Liberty Studio</p>

</div>

</body>

</html>

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有