首先呢,圣杯布局是一个非常非常古老的布局方法了,作为一个新人,感觉还是有必要学习一番的,对基础知识考察还是不错的。在学习过程中,自己也遇到了不少问题,所以今天就对圣杯布局也算是做个个人总结吧。

首先来看下圣杯布局所实现的效果:

圣杯布局指的是三列布局,其中,侧边两栏宽度固定,中间栏是自适应的。从DOM的载入顺序来讲,应该先载入left,然后是content,right。为了使中间的主要内容content先载入,所以便把中间栏content放在了前面。

即:

1 <div id="header">Header</div>
2 <div id="container">
3     <div id="content" class="column">content</div>
4     <div id="left" class="column">left</div>
5     <div id="right" class="column">right</div>
6 </div>
7 <div id="footer">Footer</div>

然后我们定义以一下基础的样式:

 1 #header,#footer{
 2     text-align: center;
 3     width: 100%;
 4     background-color: #666;
 5     height: 50px;
 6     line-height: 50px;
 7     font-size: 30px;
 8 }
 9 .column{
10     font-size: 20px;
11 }
12 #content{
13     background-color: #D6D6D6;
14     width: 100%;
15 }
16 #left{
17     background-color: #DC143C;
18     width: 200px;
19 }
20 #right{
21     background-color: #DDA0DD;
22     width: 150px;
23 }

然后我们来看下效果:

为了实现想要达到的布局效果,我们使用浮动,同时清除浮动给footer带来的影响:

1 .column{
2     float: left;
3     font-size: 20px;
4 }
5 #footer{
6     clear:both;
7 }

我们再来看下效果:

其中因为content区域的宽度是继承container的100%,所以将left与right挤到了下面。

接着,我们通过给container写内边距padding从而使left所将占的左栏以及right所将占的右栏给写出来:

1 #container{
2     padding-left: 200px;
3     padding-right: 150px;
4 }

 现在的效果是这个样子的:

为了实现最终的效果,我们需要的便是把左栏left与右栏right移到两边。首先,我们通过给left与right写margin-left使其“上位”。

即:

1 #left{
2     margin-left: -100%;
3 }
4 #right{
5     margin-left: -150px;
6 }

效果如下:

我在刚开始学习的时候不太理解为什么两边栏能通过此种方法而“上位”。我们知道,浮动的元素触碰到它父元素的边时会停止浮动,当一行不够显示的时候便换行显示,此时,正是因为中间content的宽度是100%所以将left与right挤了下去。我们其实可以抽象的想象成left与right实际上就在content的右边,如下所示:

Q:为什么left写的margin-left:100%。

A:百分比值是相关于包含该元素的块的宽度(相对于该块的百分比)。因为现在content跟container宽度一样,所以写的是100%,其实让left“左移”的宽度是content区域的宽度。

Q:为什么left与right现在是content的上面。

A:当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。(层叠准则)。

left与right覆盖在content的上面显然不是我们想要的效果,所以我们利用相对定位使其移动到container内边距的位置上。

即:

1 .column{
2     position: relative;
3 }
4 #left{
5     left: -200px;
6 }
7 #right{
8     right: -150px;
9 }

因为中间内容是流体式的,所以当窗口缩小到left+right的宽度时,content就没有了,所以还要给body写一个最小宽度:

1 body{
2     min-width: 550px;
3 }

如此一来,效果就实现咯。

由于本人知识有限,文中难免有不妥之处,希望大家能将错误指出。

谢谢!