三栏布局解决的问题
布局要求:
- 三列布局,中间宽度自适应,左右栏定宽
- 中间栏要在浏览器中优先渲染(放在文档流前面优先渲染)
- 允许任意列的高度最高
方法1:圣杯布局
步骤:
- 给三栏设置浮动,高度
- 给左右栏设置定宽 为三栏在一行并且集中在左边
- 给中间栏宽设为100%, 为中间栏在上行,左右栏在下行
- 给左右栏设置负的margin, 为与中间栏在同一行但遮挡中间栏内容
- 给父元素padding值 空出左右栏
- 给三栏添加相对定位属性,并对左右栏设置相对位置, 为左右栏移动到空位上。
.container{
padding:0 300px 0 200px; //给左右栏空出位置
height:300px;
}
.middle, .left, .right{
height:100%;
float:left;
position:relative;
}
.middle{
background: blue;
width: 100%; //中间栏内容占满父盒子的内容宽度
}
.left{
background: green;
width:200px;
margin-left:-100%; //左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。
left:-200px; //左右两栏用相对布局并分别配合right和left属性,使两栏移动后不遮挡中间div
}
.right{
background: red;
width:300px;
margin-left:-300px;
right:-300px;
}
.clear{
clear:both; //记得清楚浮动
}
<div class="container">
<div class="middle">middle</div>
<div class="left">left</div>
<div class="right">right</div>
<div class="clear"></div>
</div>
方法2:双飞翼布局
步骤:
- 给三栏设置浮动,高度
- 给左右栏设置定宽 结果为三栏在一行并且集中在左边
- 给中间栏宽设为100%, 结果为中间栏在上行,左右栏在下行
- 给左右栏设置负的margin,结果为与中间栏在同一行但遮挡中间栏内容
- 给中间栏设置子div,并对子div设置左右margin值, 空出左右栏
.container{
height:300px;
}
.middle, .left, .right{
height:100%;
float:left;
}
.middle{
background: blue;
width: 100%; //中间栏内容占满父盒子的内容宽度
}
.main{
margin:0 300px 0 200px; //给内部div添加margin,把内容放到中间栏,其实整个背景还是100%
height:100%;
}
.left{
background: green;
width:200px;
margin-left:-100%;
}
.right{
background: red;
width:300px;
margin-left:-300px;
}
.clear{
clear:both;
}
<div class="container">
<div class="middle">
<div class="main">main</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
<div class="clear"></div>
</div>
最终界面是一样的
对比图
圣杯,双飞翼布局的区别
圣杯布局和双飞翼布局解决问题的方案在前一半是相同的:三栏全部浮动,给左右两栏加负的margin值让其与中间栏div并排,以形成三栏布局。
不同在于解决“中间栏div内容不被遮挡”问题的思路不一样
- 圣杯布局:为了中间div内容不被遮挡,将三栏的父元素设置左右padding值后,将左右两个div用相对布局position:relative并配合left和right属性,使得左右两栏div移动后不遮挡中间div
- 双飞翼布局:为了中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,对子div设置左右margin值为左右两栏div空出位置。
总结:双飞翼布局比圣杯布局多了一个div,但不用相对布局position:relative了
再回顾一遍两个布局的步骤:
圣杯布局
- 给三栏设置浮动,高度
- 给左右栏设置定宽 为三栏在一行并且集中在左边
- 给中间栏宽设为100%, 为中间栏在上行,左右栏在下行
- 给左右栏设置负的margin, 为与中间栏在同一行但遮挡中间栏内容
- 给父元素padding值 空出左右栏
- 给三栏添加相对定位属性,并对左右栏设置相对位置, 为左右栏移动到空位上。
双飞翼布局
- 给三栏设置浮动,高度
- 给左右栏设置定宽 结果为三栏在一行并且集中在左边
- 给中间栏宽设为100%, 结果为中间栏在上行,左右栏在下行
- 给左右栏设置负的margin,结果为与中间栏在同一行但遮挡中间栏内容
- 给中间栏设置子div,并对子div设置左右margin值, 空出左右栏
从第5步开始不同
方法3:Flex布局
步骤:
- 将三栏的父盒子设置为flex容器
- 给右栏设置order属性将其排在第一位置上
- 给中间栏设置flex-grow属性目的让空余的空间用main来填充
- 给左右栏设置flex-basis,固定宽度
.container{
display: flex;
min-height: 130px;
}
.main{
flex-grow: 1; //定义项目放大比例,默认为0。这里让空余的空间用main来填充
background-color: blue;
}
.left{
order: -1; //定义项目的排列顺序,越小越靠前,默认为0。这里让left布局排在前面
flex-basis: 200px;
background-color: green;
}
.right{
flex-basis: 300px; //固定项目宽度。这里让left,right定宽
background-color: red;
}
<div class="container">
<div class="main">main</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
方法4:绝对定位
绝对定位使元素的位置与文档流无关,因此不占据空间。这一点与相对定位不同,相对定位实际上被看作普通流定位模型的一部分,因为元素的位置相对于它在普通流中的位置。
使用绝对定位很方便,很多布局,使用绝对定位都能实现
.container{
position: relative;
}
.main,.right,.left{
top: 0;
height: 130px;
}
.main{
margin: 0 300px 0 200px;
background-color: blue;
}
.right{
position: absolute;
width: 300px;
right: 0;
background-color: red;
}
.left{
position: absolute;
width: 200px;
background-color: green;
left: 0;
}
<div class="container">
<div class="main">main</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
*margin-left:-100 %的问题:
margin-left:0
如果改为margin:-100% 则是向左移动了一个父元素的距离