今天看到css布局,特此研究了一下圣杯布局与双飞翼布局,因为这两种方式主要针对三栏布局,因此在与flex布局比较,做一下总结:
圣杯布局
主要用到的知识点有
浮动、相对定位、margin负值,不用添加额外标签
代码
<div class="header">header</div>
<div class="contanier">
<div class="main">我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容</div>
<div class="left"></div>
<div class="right"></div>
</div>
<div class="footer">header</div>
body{
min-width: 700px;
}
.header,.footer{
height: 80px;
background-color: #0c80fe;
clear: both;
text-align: center;
}
.contanier{
padding-left: 200px;
padding-right: 200px
}
.contanier>div{
float: left;
height: 200px;
}
.left{
background-color: #ff1f30;
left: -200px;
margin-left: -100%;
}
.right{
background-color: #00AA00;
right: -200px;
margin-left:-200px;
}
.left,.right{
width: 200px;
position:relative;
}
.main{
width: 100%;
background-color: orange;
}
该布局的主要是两侧固定,中间自适应,一开始想多的是在布局的实收按照正常的布局,然后全部左浮动,两侧定宽,中间的宽度设为自适应,但是,width: auto其实是默认的值,一般我们无需设置此值,不设置即宽度默认为auto(自适应 自动,此时中间的宽度为0,或者为文本的宽度,并不是想要的效果,而且中间不能设置固定的值,否则就不是自适应了,一般自适应的话是自动铺满剩余空间,或者占据屏幕的100%,随着屏幕大小的变化而变化,此时采取的第二种方案。(中间部分需要根据浏览器宽度的变化而变化,所以要用100%)
由于中间的宽度为100%,会把两边的div挤下去,因此要想办法将三者并排显示。
如图所示,这是没有做任何变化的样式,并且三者从左到右的顺程序为main-left-right,
被挤下的原因的是因为宽度不够,中间的内容是占据屏幕的100%,此时,.left这个div设置marign负值,由于设置设置浮动,所有的元素脱离了文档流,首先设置left-200px;发现此时.红色盒子在窗口的最右边,
按照这个方法,将margin-left设置为-100%;屏幕的宽度,left这个盒子跑到最左边,同理right这是设置margin-right:-200px;在最右边;但是此时两侧的盒子会遮盖中间的盒子
利用最外层的padding值,将两侧的位置留出来
及设置
.contanier{
padding-left:200px;
padding-right:200px;
}
但是加了之后左右栏也缩进来了,于是采用相对定位方法,各自相对于自己把自己挪出去,
.left,.right{
position:relative;
}
.left{
left:-200px;
}
.right{
right:-200px;
}
最终效果
双飞翼布局
但是有圣杯布局使用了相对定位,以后布局是有局限性的,而且宽度控制要改的地方也多,在改变dom结构,多添加一层标签可以简化css,这就双飞翼布局(淘宝UED),
<body>
<div class="header">header</div>
<div class="contanier">
<div style="padding: 0 200px;background-color: orange;height: 200px">
<div class="main">我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容</div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
<div class="footer">header</div>
body{
min-width: 700px;
}
.header,.footer{
height: 80px;
background-color: #0c80fe;
clear: both;
text-align: center;
}
.contanier{
/* padding-left: 200px;
padding-right: 200px*/
}
.contanier>div{
float: left;
height: 200px;
}
.left{
background-color: #ff1f30;
/* left: -200px;*/
margin-left: -100%;
}
.right{
background-color: #00AA00;
/*right: -200px;*/
margin-left:-200px;
}
.left,.right{
width: 200px;
/*position:relative;*/
}
.main{
width: 100%;
}
为了保证窗口不能缩太小无法展示左右,可以给body加上 min-width
双飞翼布局和圣杯布局的区别(参考别处)
圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,即:
中间栏宽度设置为100%
三栏全部float浮动
左右两栏加上负margin让其跟中间栏p并排,以形成三栏布局。
不同在于解决中间栏p内容不被遮挡问题的思路不一样。
圣杯布局
将三栏的外包裹层设置左右padding-left和padding-right
将左右两个p用相对布局position: relative并分别配合right和left属性,相对自身移动以便不遮挡中间p
双飞翼布局
中间p内部创建子p用于放置内容
在该子p里用margin-left和margin-right为左右两栏p留出位置
多了1个p,少用4个css属性(圣杯布局中间pp的adding-left和padding-right这2个属性,加上左右两个p用相对布局position: relative及对应的right和left共4个属性,一共6个;而双飞翼布局子p里用margin-left和margin-right共2个属性,6-2=4)。
并且双飞翼布局还有个好处,让Main变成BFC元素了,屏幕宽度缩小Main也不会被挤下去,圣杯布局就会被挤下去。
原本想将flex的内容写上,但是内容太多了,因此flex布局单独写一篇。