圣杯布局和双飞翼布局一直是前端面试的高频考点,圣杯布局的出现是来自由 Matthew Levine 在 2006 年写的一篇文章 《In Search of the Holy Grail》。 比起双飞翼布局,它的起源不是源于对页面的形象表达。在西方,圣杯是表达“渴求之物”的意思。而双飞翼布局则是源于淘宝的UED,可以说是灵感来自于页面渲染。
效果图
原本录制了一个小视频,奈何不能上传到博客中,视频中通过缩放页面可以发现随着页面的宽度的变化,这三栏布局是中间盒子优先渲染,两边的盒子框子宽度固定不变,即使页面宽度变小,也不影响我们的浏览。注意:为了安全起见,最好还是给body加一个最小宽度!
圣杯布局要求
|
圣杯布局的三种实现
【1】浮动
- 先定义好header和footer的样式,使之横向撑满。
- 在container中的三列设为浮动和相对定位(后面会用到),center要放在最前面,footer清除浮动。
- 三列的左右两列分别定宽200px和150px,中间部分center设置100%撑满
- 这样因为浮动的关系,center会占据整个container,左右两块区域被挤下去了
- 接下来设置left的
margin-left: -100%;
,让left回到上一行最左侧 - 但这会把center给遮住了,所以这时给外层的container设置
padding-left: 200px;padding-right: 150px;
,给left和right空出位置 - 这时left并没有在最左侧,因为之前已经设置过相对定位,所以通过
left: -200px;
把left拉回最左侧 - 同样的,对于right区域,设置
margin-left: -150px;
把right拉回第一行 - 这时右侧空出了150px的空间,所以最后设置 right: -150px;把right区域拉到最右侧就行了。
<!DOCTYPE html>
<html><head><meta charset="utf-8"><script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>body {min-width: 550px; /* 2x leftContent width + rightContent width */font-weight: bold;font-size: 20px;}#header, #footer {background: rgba(29, 27, 27, 0.726);text-align: center;height: 60px;line-height: 60px;}#footer {clear: both;}#container {padding-left: 200px; /* leftContent width */padding-right: 150px; /* rightContent width */overflow: hidden;}#container .column {position: relative;float: left;text-align: center;height: 300px;line-height: 300px;}#center {width: 100%;background: rgb(206, 201, 201);}#left {width: 200px; /* leftContent width */right: 200px; /* leftContent width */margin-left: -100%;background: rgba(95, 179, 235, 0.972);}#right {width: 150px; /* rightContent width */margin-left: -150px; /* rightContent width */right: -150px;background: rgb(231, 105, 2);}</style><body><div id="header">#header</div><div id="container"><div id="center" class="column">#center</div><div id="left" class="column">#left</div><div id="right" class="column">#right</div></div><div id="footer">#footer</div></body></html>
【2】flex弹性盒子
- header和footer设置样式,横向撑满。
- container中的left、center、right依次排布即可
- 给container设置弹性布局
display: flex;
- left和right区域定宽,center设置
flex: 1;
即可
<!DOCTYPE html>
<html><head><meta charset="utf-8"><script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>body {min-width: 550px; font-weight: bold;font-size: 20px;}#header, #footer {background: rgba(29, 27, 27, 0.726);text-align: center;height: 60px;line-height: 60px;}#container {display: flex;}#container .column {text-align: center;height: 300px;line-height: 300px;}#center {flex: 1;background: rgb(206, 201, 201);}#left {width: 200px; background: rgba(95, 179, 235, 0.972);}#right {width: 150px; background: rgb(231, 105, 2);}
</style><body><div id="header">#header</div><div id="container"><div id="left" class="column">#left</div><div id="center" class="column">#center</div><div id="right" class="column">#right</div></div><div id="footer">#footer</div>
</body></html>
【3】grid布局
如上图所示,我们把body划分成三行四列的网格,其中有5条列网格线
- 给body元素添加
display: grid;
属性变成一个grid(网格) - 给header元素设置grid-row: 1; 和 grid-column: 1/5; 意思是占据第一行网格的从第一条列网格线开始到第五条列网格线结束
- 给footer元素设置grid-row: 1; 和 grid-column: 1/5; 意思是占据第三行网格的从第一条列网格线开始到第五条列网格线结束
- 给left元素设置grid-row: 2; 和 grid-column: 1/2; 意思是占据第二行网格的从第一条列网格线开始到第二条列网格线结束
- 给center元素设置grid-row: 2; 和 grid-column: 2/4; 意思是占据第二行网格的从第二条列网格线开始到第四条列网格线结束
- 给right元素设置grid-row: 2; 和 grid-column: 4/5; 意思是占据第二行网格的从第四条列网格线开始到第五条列网格线结束
<!DOCTYPE html>
<html><head><meta charset="utf-8"><script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>body {min-width: 550px;font-weight: bold;font-size: 20px;display: grid;}#header,#footer {background: rgba(29, 27, 27, 0.726);text-align: center;height: 60px;line-height: 60px;}#header {grid-row: 1;grid-column: 1/5;}#footer {grid-row: 3;grid-column: 1/5;}.column {text-align: center;height: 300px;line-height: 300px;}#left {grid-row: 2;grid-column: 1/2;background: rgba(95, 179, 235, 0.972);}#center {grid-row: 2;grid-column: 2/4;background: rgb(206, 201, 201);}#right {grid-row: 2;grid-column: 4/5;background: rgb(231, 105, 2);}
</style><body><div id="header">#header</div><div id="left" class="column">#left</div><div id="center" class="column">#center</div><div id="right" class="column">#right</div><div id="footer">#footer</div>
</body></html>
文章每周持续更新,可以微信搜索「 前端大集锦 」第一时间阅读,回复【视频】【书籍】领取200G视频资料和30本PDF书籍资料