Monday, August 23 2004 2:20 PM
很多的Web站点都使用了基本的三栏页面设计结构,或在其上稍加修改。标准的设计结构通常包括了一个位于顶部的全宽度页面头部,然后下面是一个划分为三栏的区域,包括中间的主要内容栏,边上的导航链接以及其他选项条目,最后在底部有一个全宽度的页脚,由此构成了一个基本的设计结构。
采用多栏设计结构的一个困难在于如何使各栏的背景颜色能够纵向完全填充每栏。对于所有栏都采用相同背景颜色的设计来说这并不麻烦,但要为每一栏创建单独的背景颜色则会带来一些问题。 困难在于divs垂直扩展仅仅够适应自己的内容。因此,如果采用将一种背景颜色指定到相应页面栏div的直观办法,将不会实现所需要的使颜色纵向完全填充栏的效果。相反,颜色填充将会在div内容的末尾结束。 在可以估计出哪一栏最长的情况下,使用wrapper di为较短的栏(可以参考前面的文章)创建背景颜色是一种有效的解决方案。但设计一种适合不同栏高度组合的三栏结构则需要另一种方法。 从三栏流动布局(liquid layout)开始借助CSS创建流动布局的基本技巧在于使用浮动(floats)方式将外部栏推倒浏览器窗口的左右两边,然后允许将主内容部分嵌在外部栏之间的中间部分。对中间栏设置左右边距(margin)可以将主内容限制在一个合适的垂直区域,而不是扩展到边上的栏。边上的栏需要固定宽度,但中间栏则可以根据浏览器窗口自由扩展,这就实现了流动布局(在以前的栏目中可以找到对此技术的详细叙述)。 以下给出了对于全宽度页面头部和页脚的三栏设计结构代码,如图A所示。 首先是CSS样式: body { margin: 0px; padding: 0px; } div#header { text-align: center; background-color: #CCCCCC; height: 60px; margin: 0px; padding: 1px; } div#navcol { padding: 10px; width: 130px; float: left; } div#main { padding: 10px; margin-left: 160px; margin-right: 160px; } div#sidecol { padding: 10px; width: 130px; float: right; } div#foot { border-top: solid #000 1px; background-color: #CCCCCC; padding: 10px; text-align: center; clear: both; } 然后是XHTML标记(为了使代码看起来简洁,这里通过一个简单的未排序列表显示两边栏divs,并简化了主内容以及页脚的文本)。
<body> <div id="header"> <h1>Header Text</h1> </div> <div id="navcol"> <h4>Nav Column</h4> <ul> <li>Let me not to the marriage of true minds</li> <li>Admit impediments; love is not love</li> <li>Which alters when it alteration finds</li> <li>Or bends with the remover to remove</li> <li>Oh, no, it is an ever fixed mark</li> <li>Let me not to the marriage of true minds</li> </ul> </div> <div id="sidecol"> <h4>Starboard Side Column</h4> <ul> <li>Let me not to the marriage of true minds</li> <li>Admit impediments; love is not love</li> <li>Which alters when it alteration finds</li> <li>Or bends with the remover to remove</li> </ul> </div> <div id="main"> <h2>Main Content</h2> <p> That looks on tempests ... taken.</p> <p>That looks on tempests ... taken.</p> <p>If this be error ... height be taken.</p> <p>That looks on tempests ... remove.</p> </div> <div id="foot"> <p>Footer text goes here. ... </p> </div> </body> 但这并不是我们想要的效果。 |
添加栏背景颜色
解决方案将添加一对divs作为栏内容divs的容器(container),然后使用这些容器来创建栏背景。一个div (column2)创建了包括背景颜色以及一张背景图片的两栏,另一个div (column1)则使用另一张背景图片创建了第三栏。背景图片是小型的GIF文件,仅有一像素高,以适应所创建的任何宽度的栏(本例中为150像素)。栏内容divs将背景透明化,然后设置将栏中的文本放在相应背景颜色或图像上。
为了对新的divs设置新的样式,我们在CSS样式列表中添加了如下的样式代码:
div#column2 {
margin: 0;
padding: 0;
background-image: url(side2.gif);
background-position: right;
background-repeat: repeat-y;
width: 100%;
background-color: #FFFF99;
}
div#column1 {
margin: 0px;
padding: 0px;
background-image: url(side1.gif);
background-repeat: repeat-y;
width: 100%;
}
为了确保背景divs能够完整的包括浮动栏内容,我们还需要对代码添加一个清除元素(clearing element),并把下面的样式加入到样式列表中。此样式采用了一个class selector而不是一个id,这样将有助于在整个站点范围进行样式重用。
.clear {
clear: both;
display: block;
height: 1px;
overflow: hidden;
margin: 0;
padding: 0;
}
以下是添加了divs的XHTML标记:
<body>
<div id="header">
<h1>Header Text</h1>
</div>
<div id="column2">
<div id="column1">
<div id="navcol">
<h4>Nav Column</h4>
<ul>
<li>Let me not to the marriage of true minds</li>
<li>Admit impediments; love is not love</li>
<li>Which alters when it alteration finds</li>
<li>Or bends with the remover to remove</li>
<li>Oh, no, it is an ever fixed mark</li>
<li>Let me not to the marriage of true minds</li>
</ul>
</div>
<div id="sidecol">
<h4>Starboard Side Column</h4>
<ul>
<li>Let me not to the marriage of true minds</li>
<li>Admit impediments; love is not love</li>
<li>Which alters when it alteration finds</li>
<li>Or bends with the remover to remove</li>
</ul>
</div>
<div id="main">
<h2>Main Content</h2>
<p> That looks on tempests ... taken.</p>
<p>That looks on tempests ... taken.</p>
<p>If this be error ... height be taken.</p>
<p>That looks on tempests ... remove.</p>
</div>
<div class="clear"> </div>
</div>
</div>
<div id="foot">
<p>Footer text goes here. ... </p>
</div>
</body>
代码分析
由于我们需要在两个不同的位置放置背景图片,在栏内容divs周围有两个wrapper divs。样式div#column2创建了中间和右边的栏,背景颜色为#FFFF99;定义中间栏颜色以及背景图片(background-image: side2.gif)的rule创建了左边栏。背景图片被放在div的右边(background-position: right),并且垂直重复(background-repeat: repeat-y)。div是浮动的(float: left),因此它将作为浮动内容divs遵循相同的放置规则。
类似,样式div#column1创建了包括另一张背景图片(background-image: side1.gif)的左栏。它位于div左边(background-position: left),同样进行垂直重复(background-repeat: repeat-y)。对于这一div没有采用背景颜色,因此iv#column2的背景可以被显示出来。
两个外部栏内容div(div#navcol and div#sidecol)的宽度属性(width: 150px)严格符合相应栏的背景图片尺寸。在本例中,外部栏的宽度是相同的,但也可以根据页面设计的实际需要设置为不同。
采用这种方法的一个诀窍是清除元素(<div class="clear"> </div>),它放在主内容div的下面。这正是将背景divs下拖同最长栏底部相接的关键。清除元素仅仅是一种包括非断行空格符的div。它接在被周围divs封装的元素组中最后一个非浮动元素的后面。在本例中,即主内容div。类样式.class包括了clear: both以及强制其嵌入到两边为浮动元素位置的rule。这有效的将清除元素放置到栏的底部。
背景divs必须扩展到页面底部,这样才能把清除元素包括进去,因此必须保证背景颜色和图像都能够扩展到符合页面栏整个高度的程度。剩下的.clear样式属性保证了它将被作为一个block element不被显示出来(注意:由于Netscape将忽略高度为0px的元素,因此需要将高度设置为1px而不是0)。
使用这种技术你可以创建背景颜色能够扩展到各栏全部高度的三栏结构,而无需考虑哪一栏要长一些。图D和图E显示了页面是对结果如何进行自动调整以适应栏长度的各种改变的。