圣杯和双飞翼都旨在实现三列的布局,中间内容宽度自适应,两边内容宽度固定。
特别注意的是查找了许多资料发现竟然几乎没有资料提到过这两个模型的高度问题,即使是网上给的代码也几乎没有实现高度自适应的问题,也许大家都觉得太简单甚至不值一提,但是我却为此纠结了很久,所以下面我也会提到如何实现高度自适应。
两者的区别我总结为三点:
1、DOM结构不同,相对于圣杯,双飞翼为中间内容单独加了一个容器以便margin来为左右留出空白;
2、圣杯用padding来为左右留白,双飞翼用margin;
3、圣杯要结合浮动和定位来使左右定位,双飞翼只用浮动即可。
下面分开讲解圣杯和双飞翼的实现:
圣杯模型:
圣杯最早的文章详见:点击打开链接,这篇文章十分详细地介绍了圣杯布局的实现步骤,以及各个步骤的作用。
DOM结构:
<div class="head">head<br /></div>
<div class="main">
<div class="middle">middle</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
<div class="footer">footer</div>
CSS:
<style>
* {
margin: 0;
padding: 0;
}
body {
min-width: 600px;
}
.head,
.footer {
width: 100%;
height: 50px;
text-align: center;
line-height: 50px;
background-color: #A9A9A9;
}
.left,
.middle,
.right {
float: left;
position: relative;
min-height: 200px;
margin-bottom: -2000px;
padding-bottom: 2000px;
}
.main {
padding: 0 200px;
overflow: hidden;
/*目的:使父div具有高度*/
}
.middle {
width: 100%;
background-color: red;
}
.right {
width: 200px;
background-color: blue;
margin-right: -200px;
}
.left {
width: 200px;
background-color: green;
margin-left: -100%;
left: -200px;
}
.footer {
clear: both;
}
</style>
main的部分是主要讨论的部分,怎么让三个部分显示在一排呢,我们首先想到的是使用浮动,但是存在一个问题就是怎样让宽度合理的分配?我尝试过使用百分比和固定宽度来实现相同效果,但是当浏览器缩小到一定程度时,会导致内容下移到下一行。
所以圣杯模型很好地解决了这个问题:让中间的内容优先渲染并独占一行,通过定位来使左右的模块固定在两边。
1、设置中间的内容宽度为100%,左右内边距为左右模块需要的宽度(我在做的时候会出现左右滚动条的情况,有时候又没有,无解,只有后面去了解原因了。);
2、设置左右内容的宽度,并为左中右三个模块设置左浮动此时的页面效果为:
3、这一步最为关键,将三个模块的设为相对定位,left给一个margin-left:-100%,righ给margin-left值为本身宽度的负值,这能使left和right模块上移到上一行,达到下面的效果:
4、将left左移即可:
细节:
1、为各个模块设置最小高度和宽度,使整个模型更加规范和易于理解和操作以及出现一些简单的问题;
2、为三个模块的父模块设置overflow属性为hidden使父div具有相同的高度,还有下面的用途;
3、自适应高度问题:
在最后的时候如果不能实现两边高度自适应中间高度的话会出现如下情况:
中间内容高于两边内容,但是由于三个模块本身使独立的,左右两边只会根据本身的内容来改变高度。那怎么解决这个问题呢,其实很简单,在上面链接的文章里其实提到了一个Equal Height的问题,可以参考文章:Equal Height,通过文章我们可以知道解决这类问题都可以使用:
(1)、设置父模块overflow属性为hidden;
(2)、margin-bottom: -bigValue;
padding-bottom:bigValue; 该bigValue值要足够大,跟最高的元素接近甚至比他大。
这样就解决了高度自适应的问题:
圣杯模型到此结束。
双飞翼模型:
由淘宝UED提出,网上流行的参考版本为:双飞翼模型
双飞翼模型在圣杯模型的基础上为中间 内容添加容器,使用margin来为左右留白,不用定位就可实现相同效果。
DOM结构:
<div class="head">head</div>
<div class="container">
<div class="main">
<div class="center">middle</div>
</div>
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="footer">footer</div>
CSS:
<style>
* {
margin: 0;
padding: 0;
}
.head,
.footer {
width: 100%;
height: 50px;
text-align: center;
line-break: 50px;
background-color: #C0C0C0;
}
/*container只是为了让DOM结构看着更加合理*/
.container {
overflow: hidden;
}
.main {
width: 100%;
}
.center {
margin-left: 200px;
margin-right: 200px;
background-color: #F5704F;
}
.left,
.right,
.main {
float: left;
min-height: 130px;
margin-bottom: -2000px;
padding-bottom: 2000px;
}
.left {
width: 200px;
background-color: darkgoldenrod;
margin-left: -100%;
}
.right {
width: 200px;
background-color: cadetblue;
margin-left: -200px;
}
.footer {
clear: both;
}
</style>
相对于圣杯,双飞翼的代码简单很多,有些原理也是相通的就不一一赘述了,效果如下:
知乎的这篇文章也还不错:点击打开链接
最后:也不知道会不会有人看到,上面只是自己作为学习的总结还不足以作为参考,还有很多问题我不懂,比如Equal Height的实现原理,定位的具体实现原理,浏览器横向滚动条的问题等等,自己的水平还不够,如果这篇文章有幸被你看到,你能解决我的疑惑或是对我的总结有所见解和指正,那我将感到荣幸之至。
---------------------
from https://blog.csdn.net/PethZhang/article/details/78319151