之前看过极客学院关于圣杯和双飞翼布局的视频,没做笔记,导致后来只知道有这么个事,具体细节记不得了,赶紧再看一遍,做点笔记。
圣杯布局和双飞翼布局解决的问题是一样的,就是两边顶宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。
圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏全部float浮动,但左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。不同在于解决”中间栏div内容不被遮挡“问题的思路不一样:圣杯布局,为了中间div内容不被遮挡,将父元素div.article设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。双飞翼布局,为了中间div内容不被遮挡,直接在中间div.middle内部创建子div.inner用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置。
双飞翼布局比圣杯布局多创建了一个div,但不用相对布局了。
下面是整个流程:
css部分:
<style type="text/css">
.article .left{
background:blue;
float:left;
}
.article .right{
background: green;
}
</style>
HTML部分:
<div class="article">
<div class="left">
我是左我是左
</div>
<div class="right">
我是右我是右!
</div>
float:left以后,我是左飘出文档流,浮于上方,长短随内容多少而自由伸缩。此时想给right一个5px的留白,用margin-left:5px不起作用,因为left骑在right上,其实right占据了一整行,所以只能将left加一个margin-right:才能实现如下效果:
此上也是一般的二列布局,对于三列布局,我们如下:
HTML:
<div class="left">
我是左我是左
</div>
<div class="middle">
我是中间
</div>
<div class="right">
我是右我是右
</div>
CSS:
.article .left{
background:blue;
float:left;
}
.article .right{
background: green;
float: right;
}
.article .middle{
background:darkred;
}
结果如下:
我是右被挤掉了,我是左骑于我是中间上,因为我是左脱离了文档流,我是中间则顶了上来,占据整行,将我是右挤了下去。 若我想都在一行呢?此时可以将元素换一下位置,使顺序成为left,right,middle。如下:
<div class="left">
我是左我是左
</div>
<div class="right">
我是右我是右
</div>
<div class="middle">
我是中间
</div>
结果如下:
此时,我是左,我是右在同一行浮于上方,我是中间顶上来占据了一整行,可以用opacity检验。
(注意:都是字上来把原行的字挤走了而非骑于上方,当.midddle{text-aline:right}时,结果如下:)
问题: html文档流从上至下解析,我们的middle是最重要的,我们希望middle最先渲染,所以需要把middle元素放于html的最上方,而与其余两元素仍在同一行,这就是我们要说的圣杯布局和双飞翼布局。
html:
<div class="middle">
我是中间
</div>
<div class="left">
我是左我是左
</div>
<div class="right">
我是右我是右
</div>
css:
.article .left{
width: 150px;
height: 16px;
background:blue;
float:left;
}
.article .right{
background: green;
float: right;
width: 100px;
height: 16px;
}
.article .middle{
background:darkred;
}
结果:
可以看到,分居两行,于是将.middle{float left;}我们再将.middle{width:100%},此时,我是中间是浮动元素,但又占据了100%的宽度,我们看看效果:我们将.left{margin-left:-100%}此时,再将right改为{float:left; margin-left:-100px}此时,位置站对了,可是我是中间的内容没了,我们将包围着3个元素的父元素.article{padding-left:150px;padding-right:100px},,.left{position:relative;left:-150px;} .right{position:relative;right:-100px;}
此时的css为:
<style type="text/css">
.article{
padding-left:150px;
padding-right:100px;
}
.article .left{
width: 150px;
height: 16px;
background:blue;
float:left;
margin-left: -100%;
position:relative;
left:-150px;
}
.article .right{
background: green;
width: 100px;
height: 16px;
float: left;
margin-left:-100px;
position:relative;
right:-100px;
}
.article .middle{
background:darkred;
float: left;
width: 100%;
}
</style>
此上为圣杯布局:它更改了文档流,对技术要求高,若此后我想改页面中的布局,或想把元素改为absolute,水平不过关的话可能出现各种问题。于是淘宝UED提出了双飞翼布局,它与圣杯布局一个最大的不同就是它强调在我是中间外加一个div,不让外面的东西设为relative,即双飞翼去掉了圣杯中的各个relative,如下:
html
<div class="article">
<div class="middle">
<div class="inner">我是中间</div>
</div>
<div class="left">
我是左我是左
</div>
<div class="right">
我是右我是右
</div>
css:
<style type="text/css">
/* .article{
padding-left:150px;
padding-right:100px;
}*/
.article .left{
width: 150px;
height: 16px;
background:blue;
float:left;
margin-left: -100%;
/* position:relative;
left:-150px;*/
}
.article .right{
background: green;
width: 100px;
height: 16px;
float: left;
margin-left:-100px;
/*position:relative;
right:-100px;*/
}
.article .middle{
background:darkred;
float: left;
width: 100%;
}
</style>
结果如下:
现在只需要解决一个问题,就是我是中间被挡住了,因为我们加了inner,所以,.inner{margin-left:150px; margin-right:100px}
结果如下:
此为双飞翼布局。