1.引言
朋友面试带回来一个面试题:三列布局,两边定宽,中间自适应。他说当时他是没有反应过来的,当然我也是第一次碰到这种问题(声明:我们都是新手,我本人也不是做前端的,只是比较感兴趣,自学而已),于是我利用周末的时间尝试着去实现了一下这种布局,下面我将给出我的实现方式,并着重阐述我对于圣杯布局和双飞翼布局的理解。本篇不在于“传道”,只是方便本人以后复习查阅。文中若有纰漏或者错误,欢迎指出,不必顾忌本人颜面。
2.我的思路
思路无外乎两种:一种是浮动,左右各浮动一个,中间的内容使用margin来实现中间部分的自适应;另一种是是定位,左右各绝对定位一个,中间依然使用margin来完成自适应布局。
A)思路1:浮动+margin
<div class="container">
<div class="sub">次要内容</div>
<div class="extra">额外内容</div>
<div class="main">主要内容</div>
</div>
.container{
margin: 30px;
height: 400px;
position: relative;
}
.main{
height: 400px;
background-color: yellowgreen;
margin: 0 210px;
}
.sub{
width: 200px;
height: 400px;
background-color: green;
float: left;
}
.extra{
width: 200px;
height: 400px;
background-color: grey;
float: right;
}
缺陷:这种布局存在的问题还是比较明显的,第一,html的结构中的主要内容块必须放在下面,让浮动块放在上面,这样的话主要内容就不会先渲染了。第二,当视口缩小的时候,右侧浮动的元素会被“挤下去”。
B)思路2:绝对定位+margin
<div class="container">
<div class="sub">次要内容</div>
<div class="extra">额外内容</div>
<div class="main">主要内容</div>
</div>
.container{
margin: 30px;
height: 400px;
position: relative;
overflow: hidden;
zoom: 1;
}
.main{
height: 400px;
background-color: yellowgreen;
margin: 0 210px;
}
.sub{
width: 200px;
height: 400px;
background-color: green;
position: absolute;
left: 0;
}
.extra{
width: 200px;
height: 400px;
background-color: grey;
position: absolute;
right: 0;
}
缺陷:这种布局也存在html结构固化,改变则会导致布局错乱的问题,主要的渲染块儿必须放在后面。
基于上面两种布局都存在一些问题,查找资料后发现了两种著名的“三列布局”,即圣杯布局和双飞翼布局。这两种布局实际上是时差不多的,只不过在中间自适应块儿的处理上不同。
3.圣杯布局
说真的,不知道为什么叫圣杯布局,顾名不能思义啊,布局很好的解决了先渲染主要模块儿的问题。
<div class="container">
<div class="main">主要内容</div>
<div class="sub">次要内容</div>
<div class="extra">额外内容</div>
</div>
.container{
margin: 30px;
height: 400px;
/*
padding: 0 210px;
*/
}
.main{
width: 100%;
float: left;
height: 400px;
background-color: yellowgreen;
}
.sub{
float: left;
width: 200px;
height: 400px;
background-color: green;
/*
margin-left: -100%;
position: relative;
left: -210px;
*/
}
.extra{
float: left;
width: 200px;
height: 400px;
background-color: grey;
/*
margin-left: -200px;
position: relative;
right: -210px;
*/
}
第一步:左中右块儿都向左浮动,看看效果(由于滚动条出现,下面部分截图没有截全,但不影响)
第二步:利用上一篇中讲到的负外边距布局原理 初识负外边距在布局中的影响(1):基础理论 给左边块加上“margin-left: -100%;”给右边块加上“margin-left: -200px;”但是这样的话左右两边将会“盖住”主要内容块儿,看看效果
第三步:给container加padding: 0 210px;使得左右两边“空出来”,看看效果
第四步:让左右两边“挪位置”,从而达到布局效果,显然是用相对定位。给extra加上{position: relative; right: -210px;},给sub加上{position: relative;left: -210px;},看看效果
4.双飞翼布局
上面的圣杯布局在第二步的效果上使用padding+negative margin从而实现布局效果,双飞翼布局和圣杯布局就是在这里的处理不同,双飞翼布局是使用了一个“嵌套块儿”套在main块儿里面,然后使用margin来达到布局效果。
<div class="container">
<div class="main">
<div class="main-wrap">主要内容</div>
</div>
<div class="sub">次要内容</div>
<div class="extra">额外内容</div>
</div>
.container{
margin: 30px;
height: 400px;
overflow: hidden;
zoom: 1;
}
.main{
float: left;
width: 100%;
height: 400px;
background-color: yellowgreen;
}
.sub{
float: left;
width: 200px;
height: 400px;
background-color: green;
margin-left: -100%;
}
.extra{
float: left;
width: 200px;
height: 400px;
background-color: grey;
margin-left: -200px;
}
.main-wrap{
margin: 0 210px;
height: 400px;
background-color: #674367;
}
中间的“间隙”(上图红色框)的背景色是来自main块儿的背景色,由于上面的圣杯布局解释的很详细,这里就不多解释了,应该一目了然,嵌套块儿来个margin: 0 210px;就齐活儿了,不用向圣杯布局那样使用相对定位。
5.总结
首先我个人思路的两种解决方案还是存在问题的主要是效率上的问题,虽然实现了但是不提倡,那么对于圣杯布局和双飞翼布局的两种经典的三栏布局,上面也有提到过,实际上只是在左中右三栏都浮动后的处理方式不同,圣杯布局采用的是padding+相对布局,而双飞翼布局采用的则是加一个嵌套块儿,然后给个正的margin值即可。有一点很明显,圣杯布局和双飞翼布局均采用了negative margin影响布局,在思路上不是很容易接受,但是确实是很有用处哦。