有关 HTML 水平垂直居中问题的讨论

[color=#345286] 关于 HTML 水平垂直居中问题,网上的讨论已经是相当地多了。这里,我把网上搜索的结果,并附加上解题思路,总结出来,希望对大家有所帮助。[/color]

[color=#345286] 首先,我们需要明确一个概念,[b]到底是谁要相对于谁水平垂直居中,相应的样式应该写在谁的里面。[/b]这里,我们统称为:[b]inner element[/b] 相对于 [b]outer element[/b] 水平垂直居中。下面首先讲到的是文字在 div 中居中,这个不属于这个范畴。因为盛放文字的 div 若是置于其它的 div(outer div) 中,而且文字 div 要整体相对于这个层居中,这才是我们要讨论的话题。这个时候,盛放文字的层就是 inner element,它所相对于的那个层居中的元素就是 outer element。[/color]

[color=#FF0000] [b]我们首先先看看如何使得某段文字处于 div 水平和垂直方向的中间,下面分情况来讨论。[/b][/color]

[color=#345286] [b]1. 单行文字[/b][/color]
[color=#345286] 单行文字,有两种情况:① div 的高度显示指定;② div 的高度未指定。对于 ②,文字的字体大小就决定了 div 的高度,此种情况没有必要讨论。对于 ①,只需要将 line-height 的值设置的和 height 值一致即可。至于宽度,没指定,写多少字就多宽,指定了宽度,设置 text-align 为 center 即可。[/color]





我确保这段文字就只有一行。



[color=#345286] [b]2. 多行文字(div 的高度未知)[/b][/color]
[color=#345286] 这种情况,div 的高度是随文字的多少而变化的。只需设置 padding 值即可,看你需要 padding 多少了,比较随意。[/color]





    如果一段内容,它的高度是可变的那么我们就可以使用使得上下的 padding 值相同的方法即可。同样的,这也是一种 "看起来" 的垂直居中方式,它只不过是使文字把 div 完全填充的一种访求而已。



[color=#345286] [b]3. 多行文字(div 的高度指定,即固定高度的 div)[/b][/color]
[color=#345286] CSS 中的 vertical-align 属性只会对拥有 valign 特性的 (X)HTML 标签起作用,但是在 CSS 中还有一个 display 属性能够模拟 ,所以我们可以使用这个属性来让
模拟
就可以使用 vertical-align了。注意,display:table 和 display:table-cell 的使用方法,前者必须设置在父元素上,后者必须设置在子元素上,因此我们要为需要定位的文本再增加一个
元素。[/color]







    CSS 中的 vertical-align 属性只会对拥有 valign 特性的 (X)HTML 标签起作用,但是在 CSS 中还有一个 display 属性能够模拟 table,所以我们可以使用这个属性来让 div 模拟 table 就可以使用 vertical-align了。注意,display:table 和 display:table-cell 的使用方法,前者必须设置在父元素上,后者必须设置在子元素上,因此我们要为需要定位的文本再增加一个 div 元素。



[color=#345286] 这个方法应该是很理想了,但是不幸的是,只有标准浏览器中(FF,Opera, Safari,IE8 等)才能正确地理解 display:table 和 display:table-cell,因此这种方法在不支持 W3C 标准的浏览器(IE6 和 IE7)下是无效的。嗯,这让人很郁闷!不过我们还其它的办法。[/color]

[color=#345286] 在不支持 W3C 标准的 IE 浏览器中,在高度的计算上存在着缺陷的。对父元素进行定位后,如果再对子元素进行百分比计算时,计算的基础似乎是有继承性的(如果定位的数值是绝对数值没有这个问题,但是使用百分比计算的基础将不再是该元素的高度,而从父元素继承来的定位高度)。例如,我们有下面这样一个(X)HTML代码段:[/color]







[color=#345286] 现在,outer 层就是我们的大容器,在 Firefox,Chrome 等现代浏览器中,使用两个层(包括外围的容器层),并使用 display 和 vertical-align 属性即可垂直居中。这里,IE6 和 IE7 需要三个层(包括外围的容器层)。outer 层的宽高度已知,content 层的高度未知,因为我们不知道 content 层要写多少文字,所以我们引入了 inner 层,它将 content 层包裹起来,这样,content 层里有多少文字,那么,inner 层的高度就和 content 层的高度一样(这还依赖于它们各自 position 的设置),都为文字占用的高度。不过,我们仍然要记住,inner 层和 content 层的高度是未知的。我们使 inner 层的 position 为 absolute(若为 relative,那么 inner 层的宽度将继承 outer 层的宽度,这不是我们想要的效果,我们要的效果是和 content 层一致的宽高度),top 为 50%,那么,inner 层的左上角位于 outer 层垂直方向上的正中间(50% 是根据 outer 层的高度来计算的,计算的基础是它父亲元素的高度)。这个时候,我们只需要将 content 层的位置向上偏移 content 或 inner 层的高度的一半即可。可惜,我们并不知道它们的高度。这就是为什么我们要引入三个层的原因了。由于 innner 层的 position 为 absolute,如果 content 层的 position 也为 absolute,那么 inner 层将没有高宽度,我们只能使 content 层的 postion 为 relative,只有这样,inner 层和 content 层才会有相同的高宽度。在 content 层上设置 top 为 -50%,那么它就是按 outer 层的高度来计算了。这样就达到我们的目的了。[/color]








    现在,outer 层就是我们的大容器,在 Firefox,Chrome 等现代浏览器中,使用两个层(包括外围的容器层),并使用 display 和 vertical-align 属性即可垂直居中。这里,IE6 和 IE7 需要三个层(包括外围的容器层)。outer 层的宽高度已知,content 层的高度未知,因为我们不知道 content 层要写多少文字,所以我们引入了 inner 层,它将 content 层包裹起来,这样,content 层里有多少文字,那么,inner 层的高度就和 content 层的高度一样(这还依赖于它们各自 position 的设置),都为文字占用的高度。不过,我们仍然要记住,inner 层和 content 层的高度是未知的。我们使 inner 层的 position 为 absolute(若为 relative,那么 inner 层的宽度将继承 outer 层的宽度,这不是我们想要的效果,我们要的效果是和 content 层一致的宽高度),top 为 50%,那么,inner 层的左上角位于 outer 层垂直方向上的正中间(50% 是根据 outer 层的高度来计算的,计算的基础是它父亲元素的高度)。这个时候,我们只需要将 content 层的位置向上偏移 content 或 inner 层的高度的一半即可。可惜,我们并不知道它们的高度。这就是为什么我们要引入三个层的原因了。由于 innner 层的 position 为 absolute,如果 content 层的 position 也为 absolute,那么 inner 层将没有高宽度,我们只能使 content 层的 postion 为 relative,只有这样,inner 层和 content 层才会有相同的高宽度。在 content 层上设置 top 为 -50%,那么它就是按 outer 层的高度来计算了。这样就达到我们的目的了。




[color=#345286] 为了将就 IE6 和 IE7,我们不得不使得支持 W3C 标准的浏览器(Firefox, Chrome)也使用三个层来实现居中的效果。我们也只能使用 CSS Hack 来兼容这若干个浏览器了。[/color]








    为了将就 IE6 和 IE7,我们不得不使得支持 W3C 标准的浏览器(Firefox, Chrome)也使用三个层来实现居中的效果。我们也只能使用 CSS Hack 来兼容这若干个浏览器了。





[color=#FF0000] [b]文字处于 div 的中间的问题我们已经讨论完了,现在,我们要将盛放文字的层视为 inner element。我们现在要使文字层处于这个页面的正中间,这个时候,body 就是我们的 outer element 了。[/b][/color]

[color=#345286] 这种情况,由于 inner element 的宽高度已知(其实,只是盛放文字的 div 高度被设定,文字到底有多少,还是不知道),我们首先使得 inner element 的左上角位于 outer element 的正中心。此时需要设置 inner element 的 position 为 absolute,使得其 top 和 left 均为 50%。再将 margin-top 设置为 -height/2,margin-left 设置为 -width/2。这样,就达到了我们所要的效果。[/color]












    这是一段文字,我要使得它们水平垂直居中于页面!这样的代码,在 IE6 和 IE7 下仍然不能很好的支持,而且在这两种浏览器下的效果还不一样,不管啦,只要能支持现代浏览器就行了,懒得为这些浏览器的 bug 折腾了。






[color=#345286] 事实上,上述计算 margin-left 和 margin-top 的方法并不准确。以 margin-left 为例子,准确的计算方法为:-(border-left + padding-left + width + padding-right + border-right)/2。实际操作时,几像素的差距可以忽略不计,视觉上觉得是居中的即可。若 padding 或 border 设置的值很大的话,就应该考虑精确算法了。[/color]

你可能感兴趣的:(HTML,+,CSS)