Skip to content

HTML页面布局 - 居中和高度自适应 #8

@abcrun

Description

@abcrun

对于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-topmargin-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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions