三栏式布局-圣杯与双飞翼

作者 Simmin 日期 2017-08-30
三栏式布局-圣杯与双飞翼

三栏布局的实现

圣杯和双飞翼都是经典的三栏式布局了,这类布局的特点是左右两栏定宽,中间部分宽度自适应。

这里总结一下常用的四种方法来实现三栏式布局,不过都有一定的缺点。

话不多说,先看四种方法的代码实现:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>三栏式布局-圣杯与双飞翼</title>
<style type="text/css">
.layout{
background-color: #ddd;
margin-bottom: 20px;
padding: 10px;
}
.clear:after{
content: '';
display: block;
clear: both;
}
.main,.left,.right{
float: left;
height: 125px;
}
.holy-grail{
padding: 0 180px 0 200px;
}
.holy-grail .main{
width: 100%;
background-color: lightyellow;
}
.holy-grail .left{
width: 200px;
background-color: pink;
margin-left: -100%;
position: relative;
left: -200px;
}
.holy-grail .right{
width: 180px;
background-color: lightgreen;
margin-left: -180px;
position: relative;
left: 180px;
}
.double-wings .main{
width: 100%;
}
.double-wings .center{
margin-left: 200px;
margin-right: 180px;
background-color: lightyellow;
height: inherit;
}
.double-wings .left{
width: 200px;
background-color: pink;
margin-left: -100%;
}
.double-wings .right{
width: 180px;
background-color: lightgreen;
margin-left: -180px;
}
.custom .left{
width: 200px;
float: left;
background-color: pink;
}
.custom .right{
width: 180px;
float: right;
background-color: lightgreen;
}
.custom .center{
height: 125px;
margin-left: 200px;
margin-right: 180px;
background-color: lightyellow;
}
.use-flex{
display: flex;
}
.use-flex .center{
height: 125px;
background-color: lightyellow;
flex-grow: 1;
}
.use-flex .left{
width: 200px;
background-color: pink;
flex-shrink: 0;
}
.use-flex .right{
width: 180px;
background-color: lightgreen;
flex-shrink: 0;
}
</style>
</head>
<body>
<div class="layout">
圣杯布局
<div class="holy-grail">
<div class="outer clear">
<div class="main">中间弹性区域</div>
<div class="left">左侧栏</div>
<div class="right">右侧栏</div>
</div>
</div>
</div>
<div class="layout">
双飞翼布局
<div class="double-wings clear">
<div class="main">
<div class='center'>中间弹性区域</div>
</div>
<div class="left">左侧栏</div>
<div class="right">右侧栏</div>
</div>
</div>
<div class="layout">
自定义布局
<div class="custom clear">
<div class="left">左侧栏</div>
<div class="right">右侧栏</div>
<div class="center">中间弹性区域</div>
</div>
</div>
<div class="layout">
弹性盒布局
<div class="use-flex">
<div class="left">左侧栏</div>
<div class="center">中间弹性区域</div>
<div class="right">右侧栏</div>
</div>
</div>
</body>
</html>

优缺点对比

正常情况:

正常情况

缩小窗口:

缩小窗口1

更小的窗口:

缩小窗口2

从图来看:

在外层元素不设置最小宽度时,圣杯布局表现最差,双飞翼布局最优。

圣杯布局

1.【结构】

<div class="outer clear">
<div class="main">中间弹性区域</div>
<div class="left">左侧栏</div>
<div class="right">右侧栏</div>
</div>

①外层包裹三栏,中间栏最先渲染,三栏都左浮动。
②中间栏宽度100%,左栏和右栏利用margin-left与中间栏同一行显示。
③外层元素设置padding,为左右栏留出空位。
④左右栏利用相对定位调整。

2.【缺点】

左栏的margin-left: 100%,这个百分比是相对于父元素的宽度的(这是是content-box的宽度,设置box-sizing:border-box也无效)。当窗口缩小时,父元素content-box宽度小于左栏宽度,因此做不到同一行显示。

双飞翼布局

1.【结构】

<div class="main">
<div class='center'>中间弹性区域</div>
</div>
<div class="left">左侧栏</div>
<div class="right">右侧栏</div>

①中间栏最先渲染,三栏都左浮动。
②中间栏.main宽度100%,左栏和右栏利用margin-left与中间栏同一行显示
③中间栏包含一个子元素.center,设置margin-leftmargin-right为左右栏留出空间。

2.【缺点】

和圣杯布局不同,左栏虽然仍旧是margin-left: 100%,但父元素宽度由.main撑开。但它仍旧有缺点,当窗口太小时,中间栏宽度会自适应为0,右栏元素会往左覆盖住左栏元素。

自定义布局

1.【结构】

<div class="left">左侧栏</div>
<div class="right">右侧栏</div>
<div class="center">中间弹性区域</div>

①完全利用浮动特性,左栏左浮动,右栏右浮动,中间栏自然会顶上去。
②再利用margin-leftmargin-right控制中间栏显示区。

2.【缺点】

矿口太小,左右栏不能浮动到同一行,而且中间栏显示区宽度为0。

弹性盒布局

1.【结构】

<div class="use-flex">
<div class="left">左侧栏</div>
<div class="center">中间弹性区域</div>
<div class="right">右侧栏</div>
</div>

①外层容器定义display:flex
②左右两栏定宽,并设置不缩小flex-shrink:0
③中间栏定义放大比flex-grow:1

2.【缺点】

很明显,会overflow;但是中间栏内容得到了保留。

总结

为了避免以上不良表现,给外层元素设置了最小宽度就ok啦。