-
Notifications
You must be signed in to change notification settings - Fork 10
Description
对于HTML来说,页面布局与代码结构才是最重要的,传统的页面布局中比较典型的两个问题就是:居中和高度自适应(这里不考虑弹性布局)。
水平垂直居中问题
CSS中设置居中的属性有两个:align:center;vertical-align:middle,分别代表水平居中和垂直居中,然而这两个属性并不适用所有场景。align:center适用于标签内的文本内容,如果父元素中包含其他类似于div这种划分区域的标签,那么对于非IE元素就不起作用了,需要用到margin-left:auto;margin-right:auto属性来配合处理兼容。而vartical-align:middle却仅针对内链元素有用,对于块状元素,就没有办法了。
水平居中的问题比较好解决,如上面所述,直接设置text-align:center;margin:0 auto;即可实现。然而对于垂直居中就比较复杂了,可以分为几种情况:
- 父元素/子元素高度都固定;
- 父元素高度不固定,子元素高度固定;
- 父元素高度固定,子元素高度不固定;
- 父元素/子元素高度均不固定。
对于第一种情况比较简单,可以直接根据父子元素的高度的差值设置margin-top属性即可;
第二种情况则可以设置子元素相对或者绝对与父元素top:50%即可实现子元素的左上角居中,然后通过设置margin-top和margin-left为负自身高度的一半即可。
当看到第三种场景的时候,可能会想到利用line-height等于父元素的高度或者vertical-align:middle来实现垂直居中,但是可惜的是line-height仅是针对文字的,而vertical-align却只针对内联元素。咋一看文字可以是内联元素,而vertical-align是针对内联元素,那么组合起来,我们可以利用这两种特性实现垂直居中。最后通过某些特性将文字隐藏即可。
对于第四种场景,按说第二种场景是通过百分比定位,margin-top的值如果不固定也可以用百分比来实现,看起来很理想(仅IE支持),但是对于一些浏览器却不支持(如FF)。然而对于部分浏览器却支持display:table-cell,这时所有问题就迎刃而解了。
高度自适应问题
高度自适应是比较常见的问题,尤其是 两列结构。然而就算是两列结构,也存在:两列都固定;或者一列高度固定,另一列不固定;或者两列高度都不固定的情况。同理 三列结构 更是如此。那么如何保证不定高度那列因为内容增加高度变化时,其他列能随之改变呢(需要强调:这里说的改变是视觉上的高度的变化 - 如背景色,而实际高度并不一定变化)?
对于两列或者三列这两种高度自适应结构,有一个比较典型的方案就是利用div的border表示一列,以三列为例:
<style type="text/css">
.main{width:200px;border-left:solid 200px #333;border-right:solid 200px #eee;background:#aaa;color:red;}
.left{position:relative;margin-left:-200px;width:200px;float:left;}
.center{width:200px;float:left;}
.right{position:relative;margin-right:-200px;width:200px;float:right;}
.clear{clear:both}
</style>
<div class="main">
<div class="left">这里是左侧的内容<br/>这里是左侧的内容<br/>这里是左侧的内容</div>
<div class="center">这是中间的内容</div>
<div class="right">这里是右侧的内容<br/>这里是右侧的内容<br/>这里是右侧的内容</br>这里是右侧的内容</br></div>
<div class="clear"></div>
</div>
这个时候不管是哪一部分内容增加,这三列在视觉上都会随之增高。这是一个比较典型的例子。从根源上,不管其中任何一个区域内容增加都会促使父元素.main的高度增加,由于父元素内容和边框使用三种不同的底色,所以看上去就是高度自适应。
那么再换一种思路,假设2列高度(未知)自适应(这两列分别用A,B表示,而P是他们的父元素),当A或者B高度变化时,会促使父元素P的高度变化,如果P和A都是一样的背景色,那么当B变化时,由于P的高度变化,A自然看起来是高度自适应了。然而当A变化时,虽然P高度也随之变化了,但是由于P与A的背景色一致,因此B却没有任何变化。所以这种思路不能解决问题,那么我们在换一种思路:如果A的变化可以引起B的变化,而B的变化能引起P的变化,A的背景色和P相同,这不就解决问题了吗?实现代码如下:
<style type="text/css">
.outer{background:red}
.inner{background:blue}
.con{background:red;float:left;width:200px;}
.clear{clear:both;}
</style>
<div class="outer">
<div class="inner">
<div class="con">
测试测试测试测试<br/>测试测试测试测试<br/>测试测试测试测试<br/>测试测试测试测试
</div>
内容内容内容
<div class="clear"></div>
</div>
</div>
通过这种思路,我们也可以演变出三列高度自适应的情况。
当然CSS3里面引入了一种的新的布局方式:弹性布局。弹性布局给页面的布局引入了一种新的解决方案,具体可参考MSDN关于弹性布局的介绍:http://msdn.microsoft.com/zh-CN/library/bg124109.aspx
