背景
- 现在布局一般都用flex了,最近发现考布局还有很多在考圣杯布局和双飞翼布局的,所以来研究下。
圣杯布局
html骨架
<div class="content">
<div class="center">
</div>
<div class="left">
</div>
<div class="right">
</div>
</div>
原理
- 圣杯布局原理就是父元素左右两边留出固定内边距,让左右两块塞进这个内边距里。
第一种解法
- 第一种解法就是百度到最多的解法,内部三元素全部浮动和相对定位。
- 主要技巧:
- 一、利用相对定位元素之间参照定位为最近的元素,使得每个元素可以使用margin和left来调整自身位置。
- 二、利用float元素并排显示特性,调整每个元素位置即可放入padding。
- 缺点:
- 当中间元素间距小于左边元素间距时就会发生bug,导致left位移一个自身身位不够一行,于是换到下一行。我就没懂为啥这种有明显bug的布局会那么多人抄。
.content{
padding: 0 300px;
}
.center,.left,.right{
position: relative;
min-height: 130px;
float: left;
}
.center{
background: blue;
width: 100%;
}
.left{
left:-300px;
margin-left: -100%;
background: yellow;
width: 300px;
}
.right{
background: #000;
width:300px;
left:100%;
margin-left:-100%;
}
第二种解法
- 第一种解法是利用相对位置之间进行参照,我们也可以把包裹的容器作为相对位置进行定位,然后用calc计算。
- 主要技巧:
- 利用calc来计算位置,左侧靠左边距,右侧靠右边距塞进去。
- 缺点:
- 好像没啥缺点。calc可能有兼容性问题
.content{
padding: 0 300px;
position: relative;
}
.center,.left,.right{
min-height: 130px;
float: left;
}
.center{
background: blue;
width: 100%;
}
.left{
background: yellow;
width: 300px;
margin-left: calc(-100% - 300px);
}
.right{
background: #000;
width:300px;
margin-right: -300px;
}
第三种解法
- 我们发现float可以水平排列,那么要让元素行内排列除了float还能用什么?
- 没错就是inline-block。
- 主要技巧:
- 一、由于都为行内块,所以父元素需要添加不换行属性。
- 二、由于默认font-size不为0,所以为了无偏差需要改字号。
- 缺点:
- 这种布局倒是不会出现第一种解法的bug,但是由于改了字号所以内部不适合直接放内容。
.content{
padding: 0 300px;
white-space: nowrap;
font-size: 0;
}
.center,.left,.right{
position: relative;
min-height: 130px;
display: inline-block;
}
.center{
background: blue;
width: 100%;
}
.left{
left: -300px;
margin-left:-100%;
background: yellow;
width: 300px;
}
.right{
background: #000;
width:300px;
margin-left: 100%;
right: 300px;
}
第四种解法
- 除了上面几种解法,当然还有万能的绝对定位,直接把元素塞进padding里即可。
- 主要技巧:
- 没什么技巧,就是暴力。
- 缺点:
- 好像没啥特别的缺点。
.content{
padding: 0 300px;
position: relative;
}
.center,.left,.right{
min-height: 130px;
}
.center{
background: blue;
width: 100%;
}
.left{
background: yellow;
width: 300px;
position: absolute;
top:0;
left:0;
}
.right{
background: #000;
width:300px;
position: absolute;
top:0;
right: 0;
}
双飞翼布局
html骨架
<div class="container">
<div class="main">
<div class="content"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
原理
- 前面说圣杯是父元素挖出个内边距留给两侧,这个双飞翼由于里面多了个div,所以原理就是里面的div设置外边距把位置让出来,另外2个调整位置插进去。
第一种解法
- 首先是百度的最多的解法:
- 主要技巧:
- 一、跟上面圣杯一样,也是利用float元素调整边距会在一行的特性。
- 二、跟上面有个区别,就是不需要相对定位调整位置了,于是也没有上面圣杯用相对定位的位移而产生的bug。
- 三、需要设置字体大小,不然main嵌套的content位置下移。
.left, .main, .right {
float: left;
min-height: 130px;
}
.left {
margin-left: -100%;
background: green;
width: 200px;
}
.right {
margin-left: -300px;
background-color: red;
width: 300px;
}
.main {
font-size: 0;
width: 100%;
}
.content{
margin: 0 300px 0 200px;
background: blue;
min-height: 130px;
}
第二种解法
- 用inline-block
- 由于main和content都要设置inline-block,所以导致宽度继承了body的宽度,无法获取真正的100%宽度,于是靠calc来计算。
- 主要技巧:
- 利用calc计算中间区域内容宽度以及右侧栏边距。
.left, .main, .right {
display: inline-block;
min-height: 130px;
}
.left {
background: green;
width: 200px;
margin-left: -100%;
}
.right {
background-color: red;
width: 300px;
margin-left: calc(100% - 300px - 200px);
}
.main {
width: 100%
}
.content{
margin: 0 300px 0 200px;
background: blue;
min-height: 130px;
display: inline-block;
width:calc(100% - 300px - 200px)
}
.container{
white-space: nowrap;
font-size: 0;
}
第三种解法
- 万能解法绝对定位。
- 这个没啥说的,不管什么布局都很好用。
.container{
position: relative;
font-size: 0;
}
.left {
background: green;
width: 200px;
height: 130px;
position: absolute;
top:0;
left:0
}
.right {
background-color: red;
width: 300px;
height: 130px;
position: absolute;
top:0;
right:0
}
.main{
position: relative;
}
.content{
margin: 0 300px 0 200px;
background: blue;
height: 130px;
}
总结
- 以上就是圣杯和双飞翼的各种解法,当然用flex,grid,table之类也能做出来,只是为其思想(挖内边距填位置和挖外边距填位置)试着去用各种方法做相同的布局。另外和calc类似的transform那些就不说了。
- 可以发现,这2种布局都比较老式,但还是有比较好的解法,除去万能绝对定位,圣杯布局推荐用第三种方式,双飞翼推荐用第一种方式。