文章目录
三栏式布局圣杯布局方法1:使用float布局框架 , 用margin为负值 , position: relative定位分析:代码:缺点方法2:calc方法3: flex布局方法4 定位方式布局双飞翼布局分析:代码圣杯和双飞翼异同三栏式布局
三栏布局,两边的盒子宽度固定,中间盒子自适应,“圣杯”和“双飞翼就是三栏式布局,它们实现的效果是一样的,差别在于其实现的思想。
圣杯布局
方法1:使用float布局框架 , 用margin为负值 , position: relative定位
圣杯:父盒子包含三个子盒子(左,中,右)
中间盒子的宽度设置为 width: 100%; 独占一行;使用负边距(均是 margin-left)把左右两边的盒子都拉上去和中间盒子同一行; .left {margin-left:-100%;} 把左边的盒子拉上去.right {margin-left:-右边盒子宽度px;} 把右边的盒子拉上去 父盒子设置左右的 padding 来为左右盒子留位置;对左右盒子使用相对布局来占据 padding 的空白,避免中间盒子的内容被左右盒子覆盖;
一起来看看淘宝的头部实现:
通过缩放页面就可以发现,随着页面的宽度的变化,这三栏布局是中间盒子优先渲染,两边的盒子框子固定不变,即使页面宽度变小,也不影响我们的浏览
分析:
基础布局
<div class="header">头部</div><div class="container"><div class="center">中</div><div class="left">左</div><div class="right">右</div></div><div class="footer">底部</div>
.header{width: 100%;height: 100px;background-color: rgb(228, 127, 127);}.footer{width: 100%;height: 100px;background-color: rgb(189, 85, 85);}.container{width: 100%;}.center{width:100%;height: 100px;background-color: rgb(129, 113, 221);}.left{width: 200px;height: 100px;background-color: rgb(175, 226, 133);}.right{width: 100px;height: 100px;background-color: rgb(133, 226, 221);}
浮动
出现了高度塌陷,底部footer补位上来了
给footer清除浮动带来的影响
[css] 解决问题—高度塌陷
大家可以看到,三栏并没有在父元素的一行显示,就是因为中间盒子我们给了百分之百的宽度。所有左右两个盒子才会被挤下来。
那么如何让它们呈现出一行三列的效果呢?那就要让左边的盒子要到中间盒子的最左边,右边的盒子到中间盒子的最右边。换个想法,如果中间盒子不是100%的宽度,那么按照文档流,左边的盒子一定会在中间盒子的后面显示,接着显示右边的盒子。但是现在中间盒子是满屏了的,所以左右两个盒子被挤到下一行显示。我们要做到的是让左右两个盒子都上去。此时,CSS的负边距(negative margin)该上阵了。
也可以这样理解:margin负值会改变元素占据的空间,你要是不给他负值,一定是在第二行显示,因为他占据空间,第一行没有地方放他,你要是给一个-100px,和他宽度一样,那他占据的空间就是0,自然就回跑到上面去,
利用margin-left的负值将左侧栏挪上来
左侧栏margin-left赋值为-100%
左侧上去后,右侧就往前走一走
让右侧上来,
利用margin-left的负值将右侧栏挪上来
右侧栏margin-left赋值为负的自身宽度。
注意:这里的左右侧栏都是附在内容栏上的,内容栏被压在下面。(把中间部分height扩大,这样看的清晰)
将内容栏被左右压在底下的部分,通过container添加padding属性透出来。
左右侧边栏利用position: relative,移出内容区域
把中间的紫色高度恢复为100px
代码:
先写center部分,width 100%center,left,right都是左浮动设置margin-left为负值让left和right部分回到与center部分同一行父容器container设置padding-left和padding-right设置相对定位,让left和right部分移动到两边<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.header{width: 100%;height: 100px;background-color: rgb(228, 127, 127);}.footer{width: 100%;height: 100px;background-color: rgb(189, 85, 85);clear: both;}.container{width: 100%;padding: 0 100px 0 200px;box-sizing: border-box;}.center{width:100%;height:100px;background-color: rgb(129, 113, 221);float: left;}.left{width: 200px;height: 100px;background-color: rgb(175, 226, 133);float: left;margin-left: -100%;position: relative;left: -200px;}.right{width: 100px;height: 100px;background-color: rgb(133, 226, 221);float: left;margin-left: -100px;position: relative;left: 100px;}</style></head><body><div class="header">头部</div><div class="container"><div class="center">中</div><div class="left">左</div><div class="right">右</div></div><div class="footer">底部</div></body></html>
缺点
center部分的最小宽度不能小于left部分的宽度
其中一列内容高度拉长,其他两列的高度不会自动填充
方法2:calc
兼容到IE9
html,body {height: 100%;overflow: hidden;}.container {height: 100%;}.left,.right {width: 200px;min-height: 200px;background: lightblue;float: left;}.center {width: calc(100% - 400px);min-height: 200px;background: lightsalmon;float: left;}
方法3: flex布局
html,body {height: 100%;overflow: hidden;}.container{display: flex;/*space-between:空白均匀分布到元素间*/justify-content: space-between;height: 100%;}.left,.right{/*flex:放大倍数 缩小倍数 占据大小*/flex: 0 0 200px;height: 200px;background: lightblue;}.center{/*flex:1 把剩余空间全都占据(自动分配占据空间)*/flex: 1;min-height: 200px;background: lightsalmon;}
<div class="container"><div class="left"></div><div class="center"></div><div class="right"></div></div>
方法4 定位方式布局
html, body {height: 100%;overflow: hidden;}.container{position: relative;height: 100%;}.left,.right{position: absolute;top: 0;width: 200px;min-height: 200px;background: lightblue;}.left{left: 0;}.right{right: 0;}.center{margin: 0 200px;min-height: 200px;background: lightsalmon;}
<div class="container"><div class="left"></div><div class="center"></div><div class="right"></div></div>
双飞翼布局
双飞翼:父盒子包含三个子盒子(左,中,右),中间的子盒子里再加一个子盒子。
中间盒子的宽度设置为 width: 100%; 独占一行;使用负边距(均是 margin-left)把左右两边的盒子都拉上去和中间盒子同一行;在中间盒子里面再添加一个 div,然后对这个 div 设置 margin-left 和 margin-right来为左右盒子留位置;
分析:
<div class="header">头部</div><div class="container"><!-- 中间的 div 必须写在最前面 --><div class="main"><div class="center">中间弹性区</div></div><div class="left">左边栏</div><div class="right">右边栏</div></div><div class="footer">底部</div>
从上面的DOM结构来看,双飞翼布局与圣杯布局最大的不同点便是在此,双飞翼布局中,将中间栏放在一个div内部包裹起来了,多了一层DOM结构
基础布局
为左右两列预留出空间,设置center的左右margin。
将左边栏放置到预留位置:
将右边栏放置到预留位置:
代码
先写center部分,width 100%center,left,right都是左浮动在中间盒子里再增加一个子盒子,设置子盒子的 margin-left, margin-right来让出空位,设置margin-left为负值让left和right部分回到与center部分同一行<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.header {width: 100%;height: 100px;background-color: rgb(228, 127, 127);}.footer {width: 100%;height: 100px;background-color: rgb(189, 85, 85);clear: both;}.container {width: 100%;height: 100px;}.main {width: 100%;height: 100px;background-color: rgb(129, 113, 221);float: left;}.main .center{height: 100px;background-color: rgb(233, 162, 215);margin-left: 200px;margin-right: 100px;}.left {width: 200px;height: 100px;background-color: rgb(175, 226, 133);float: left;margin-left: -100%;}.right {width: 100px;height: 100px;background-color: rgb(133, 226, 221);float: left;margin-left: -100px;}</style></head><body><div class="header">头部</div><div class="container"><!-- 中间的 div 必须写在最前面 --><div class="main"><div class="center">中间弹性区</div></div><div class="left">左边栏</div><div class="right">右边栏</div></div><div class="footer">底部</div></body></html>
圣杯和双飞翼异同
圣杯布局和双飞翼布局解决的问题是一样的,都是两边定宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。
两种方法基本思路都相同:首先让中间盒子 100% 宽度占满同一高度的空间,在左右两个盒子被挤出中间盒子所在区域时,使用 margin-left 的负值将左右两个盒子拉回与中间盒子同一高度的空间。接下来进行一些调整避免中间盒子的内容被左右盒子遮挡。主要区别在于如何使中间盒子的内容不被左右盒子遮挡: 圣杯布局的方法:设置父盒子的 padding 值为左右盒子留出空位,再利用相对定位对左右盒子调整位置占据 padding 出来的空位;双飞翼布局的方法:在中间盒子里再增加一个子盒子,直接设置这个子盒子的 margin 值来让出空位,而不用再调整左右盒子。
简单说起来就是双飞翼布局比圣杯布局多创建了一个 div,但不用相对布局了,少设置几个属性。
这样说也行
说说圣杯布局与双飞翼布局的区别吧:
相同点:
1.两个都是三栏式布局,中间栏优先放,保证优先渲染
2.实现方式都是左浮动
不同点:
1圣杯布局是中间栏为两边腾开位置。双飞翼布局则是中间栏不变,将内容部分为两边腾开位置
参考:
CSS 布局经典问题初步整理
圣杯布局和双飞翼布局
圣杯布局和双飞翼布局的理解与思考
双飞翼布局