css垂直居中问题~

css垂直居中有好几种方法:
  • 使用vertical-align属性
  • 对于确定高的元素可以margin:负半高; top:50%;
  • 绝对定位position:absolute,设置top:0; bottom:0; margin:auto;
  • 使用:before伪创建一个block元素height:50%占位
这里介绍个好页面:详解垂直居中
  1. 对于vertical-align属性,由于这是对应单行的属性,所以对于div默认多行的元素得伪装成单行比如table-cell。
    W3C官方对vertical-align做了下面的解释: This property affects the vertical positioning inside a line box of the boxes generated by an inline-level element.
    实际上,一个盒中由很多行组成,不论是span还是div的盒,都不一定只有一行,vertical-align只作用于在同一行内的元素,它的垂直并不是相对于整个盒而言的,而是对于一行而言,所以要实现效果得伪装成单行,比如设置line-height和盒高相同,或者display:table-cell,table的单元格,因为是一行内的元素,因此vertical-align按照我们的想法来工作。但有个比较麻烦的问题是,直接display:table-cell;浏览器会隐形创建table和table-row,导致width:100%等基于父盒子的值失效。如果不必考虑这个以及ie等兼容,这个方法不错。
  2. 对于50%top和负半高的margin垂直居中是比较好的方法,但是发现负margin-top居然会影响到父元素的定位。
    test
    解决办法,我使用的是对父元素设定一个border-top:1px solid transparent; margin-top:-1px;只要设定了border或者padding子元素的影响就消失了。在firefox中设定0.1px似乎子元素的影响消失,但在firebug里显示为0.1px而不是四舍五入的0px;这里没弄明白。在chrome里直接将0.1px==0px,当然子元素的影响也存在
    test
    对于top|bottom、margin-top|margin-bottom、border-top|border-bottom、padding-top|paddint-bottom、height的相对值其实蛮令人困惑的,top|bottom和height很符合常理的,百分比的值基于父元素的高,但是margin-top|margin-bottom、padding-top|paddint-bottom确实基于父元素的宽,on my god~这这~~问了google后在经典论坛得到解释:
    看起来似乎没有道理。但没有道理的东西能成为标准,说明它其实是有道理的。如果你是浏览器,如果内、外边距取值为百分数时其基数取自父元素的高度,那么你会发现你没有办法布局,会限入死循环。
    margin估计也是这样,但为啥宽就可以呢?所以始终还是没明白~希望谁能给个更好的解释,这里就谢过了。 当然这个问题也是使用top:50%;margin-top:负半高而非top:半高;margin-top:50%的原因。也是在:before的content使用height:50%;的原因。
  3. 对于:before创建占位内容来实现垂直居中是我最喜欢的,应该算首创吧,google没找到这种方法。
    推荐参考: 英文原文:http://nicolasgallagher.com/pure-css-speech-bubbles/ 腾讯isd翻译中文:http://isd.tencent.com/?p=1781
    这里在腾讯isd里有段译者注非常重要,
    译者:这里就是本文最为关键的一句话了,伪类在非IE的浏览器中竞然可以在HTML中创建一个DOM元素,并且可以用CSS来控制哦~哪么为什么伪类会表形成一个DOM元素呢,可能浏览器为了实现伪类的效果而产生的,这里则被作者发现并利用了。
    对于:before和:after的实现是创建一个dom元素,而且更重要的是,这元素是不在dom树上的,即属于css表现,所以甚至可以说没创建多余标签。而且其表现效果相当于背景,即使有文字也是无法选择的,作为定位用元素的最佳的拉。下面是效果测试:
    接着我们就可以让这:before来的元素发挥大作用拉,之所以不用:after因为after是在父元素所有子元素的最尾添加的,根据浏览器自上而下的渲染顺序,这次需要top所以:before当仁不让拉。设定父元素:before来的元素的height:50%,其效果其实等效于子元素的设定top:50%,这里之所以不用top:50%,因为top在relative定位中有更好的用处,拿来做本来应该是父元素和margin的事情显然是高射炮打蚊子——大材小用。再margin-top:负半高,完美垂直居中。
    当然对应到ie兼容的办法我想用Javascript来动态设定margin-top是比较好的方法,当然也可以类似非ie:before创建dom元素,不过这就真的创建多余标签了。 由于浏览器对于display:block的元素是自动会在渲染时在盒子后面添加换行符,除非用float:left|right来处理,所以用此法处理水平居中不知道效果如何,待研究。
posted @ 2010-12-19 20:42  Defims  阅读(218)  评论(0)    收藏  举报