三栏布局的实现
圣杯和双飞翼都是经典的三栏式布局了,这类布局的特点是左右两栏定宽,中间部分宽度自适应。
这里总结一下常用的四种方法来实现三栏式布局,不过都有一定的缺点。
话不多说,先看四种方法的代码实现:
<!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.【结构】
<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-left
和margin-right
为左右栏留出空间。
2.【缺点】
和圣杯布局不同,左栏虽然仍旧是margin-left: 100%
,但父元素宽度由.main
撑开。但它仍旧有缺点,当窗口太小时,中间栏宽度会自适应为0,右栏元素会往左覆盖住左栏元素。
自定义布局
1.【结构】
<div class="left">左侧栏</div> <div class="right">右侧栏</div> <div class="center">中间弹性区域</div>
|
①完全利用浮动特性,左栏左浮动,右栏右浮动,中间栏自然会顶上去。
②再利用margin-left
和margin-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啦。