你真的了解圣杯和双飞翼布局吗?
前言
圣杯和双飞翼布局作为面试常考的题目之一,相信大家肯定都会有着自己的一套知识储备,但是,你真的了解这两种经典布局吗?本文将介绍这两种经典布局产生的来龙去脉,以及实现这两种布局的一些方式,希望大家能够喜欢。
为什么需要圣杯和双飞翼布局
大家思考一个问题,这样一种布局,你该怎么处理呢?
常规
情况下,我们的布局思路应该这样写,从上到下,从左到右
:
<div>header</div>
<div>
<div>left</div>
<div>main</div>
<div>right</div>
</div>
<div>footer</div>
这样的三栏布局也没有什么问题,但是我们要知道一个网站的主要内容就是中间
的部分,比如像掘金:
那么对于用户来说,他们当然是希望最中间的部分首先加载出来的,能看到最重要的内容,但是因为浏览器加载dom的机制是按顺序
加载的,浏览器从HTML文档的开头开始,逐步解析
并构建文档对象模型,所以,我们想让main
首先加载出来的话,那就将它前置
,然后通过一些CSS的样式,将其继续展示出上面的三栏布局的样式:
<div>header</div>
<div>
<div>main</div>
<div>left</div>
<div>right</div>
</div>
<div>footer</div>
这就是所谓的圣杯
布局,最早是Matthew Levine 在2006年1月30日在In Search of the Holy Grail 这篇文章中提出来的;
那么完整
的效果
、实现代码
如下:
<style>
.header,
.footer {
width: 100%;
height: 200px;
background-color: pink;
}
.container {
padding: 0 100px 0 100px;
overflow: hidden;
}
.col {
position: relative;
float: left;
height: 400px;
}
.left {
background-color: green;
width: 100px;
margin-left: -100%;
left: -100px;
}
.main {
width: 100%;
background-color: blue;
}
.right {
width: 100px;
background-color: green;
margin-left: -100px;
right: -100px;
}
</style>
<div class="header">header</div>
<div class="container">
<div class="main col">main</div>
<div class="left col">left</div>
<div class="right col">right</div>
</div>
<div class="footer">footer</div>
如上述代码所示,,使用了相对定位
、浮动
和负值margin
,将left和right装到main的两侧,所以顾名:圣杯
;
但是呢,圣杯是有问题
的,在某些特殊的场景下,比如说,left和right盒子的宽度过宽
的情况下,圣杯就碎掉
了,比如将上述代码的left和right盒子的宽度改为以500px
为基准:
<style>
.header,
.footer {
width: 100%;
height: 200px;
background-color: pink;
}
.container {
padding: 0 500px 0 500px;
overflow: hidden;
}
.col {
position: relative;
float: left;
height: 400px;
}
.left {
background-color: green;
width: 500px;
margin-left: -100%;
left: -500px;
}
.main {
width: 100%;
background-color: blue;
}
.right {
width: 500px;
background-color: green;
margin-left: -500px;
right: -500px;
}
</style>
<div class="header">header</div>
<div class="container">
<div class="main col">main</div>
<div class="left col">left</div>
<div class="right col">right</div>
</div>
<div class="footer">footer</div>
正常情况下,布局还是依然正常
,只是两侧宽了
而已:
但是我们将整个窗口缩小,圣杯就碎掉了:
原因是因为 padding: 0 500px 0 500px;
,当整个窗口的最大宽度已经小于
左右两边的padding共1000px
,left和right就被挤下去了;
于是针对这种情况,淘宝UED的玉伯大大提出来了双飞翼布局
,效果和圣杯布局一样,只是他将其比作一只鸟,左翅膀、中间、右翅膀;
相比于圣杯布局,双飞翼布局在原有的main盒子再加了一层div:
<div>header</div>
<div>
<div><div>main</div></div>
<div>left</div>
<div>right</div>
</div>
<div>footer</div>
实际的效果
和代码
如下,哪怕再怎么缩,都不会被挤下去:
<style>
.header,
.footer {
width: 100%;
height: 200px;
background-color: pink;
}
.container {
padding: 0;
overflow: hidden;
}
.col {
float: left;
height: 400px;
}
.left {
background-color: green;
width: 500px;
margin-left: -100%;
}
.main {
width: 100%;
background-color: blue;
}
.main-in {
margin: 0 500px 0 500px;
}
.right {
width: 500px;
background-color: green;
margin-left: -500px;
}
</style>
<div class="header">header</div>
<div class="container">
<div class="main col">
<div class="main-in">main</div>
</div>
<div class="left col">left</div>
<div class="right col">right</div>
</div>
<div class="footer">footer</div>
圣杯布局实现方式补充
上面介绍了一种圣杯布局的实现方式,这里再介绍一种用绝对定位
的,这种方法其实也能避免
上述说的当左右两侧的盒子过于宽时,圣杯被挤破
的情况:
<style>
.header,
.footer {
width: 100%;
height: 200px;
background-color: pink;
}
.container {
position: relative;
padding: 0 100px;
}
.col {
height: 400px;
}
.left {
background-color: green;
width: 100px;
position: absolute;
left: 0;
top: 0;
}
.main {
width: 100%;
background-color: blue;
}
.right {
width: 100px;
background-color: green;
position: absolute;
right: 0;
top: 0;
}
</style>
<div class="header">header</div>
<div class="container">
<div class="main col">main</div>
<div class="left col">left</div>
<div class="right col">right</div>
</div>
<div class="footer">footer</div>
双飞翼布局实现方式补充
也是使用绝对定位
的:
<style>
.header,
.footer {
width: 100%;
height: 200px;
background-color: pink;
}
.container {
position: relative;
}
.col {
height: 400px;
}
.left {
background-color: green;
width: 500px;
position: absolute;
top: 0;
left: 0;
}
.main {
width: calc(100% - 1000px);
background-color: blue;
margin-left: 500px;
}
.main-in {
/* margin: 0 500px 0 500px; */
}
.right {
width: 500px;
background-color: green;
position: absolute;
top: 0;
right: 0;
}
</style>
<div class="header">header</div>
<div class="container">
<div class="main col">
<div class="main-in">main</div>
</div>
<div class="left col">left</div>
<div class="right col">right</div>
</div>
<div class="footer">footer</div>
其它普通的三列布局的实现
flex布局实现
<style>
* {
padding: 0;
margin: 0;
}
.header,
.footer {
width: 100%;
height: 200px;
background-color: blue;
}
.container {
display: flex;
}
.left {
width: 100px;
height: 300px;
background-color: pink;
}
.main {
flex: 1;
width: 100%;
height: 300px;
background-color: green;
}
.right {
width: 100px;
height: 300px;
background-color: pink;
}
</style>
<div class="header">header</div>
<div class="container">
<div class="left col">left</div>
<div class="main col">main</div>
<div class="right col">right</div>
</div>
<div class="footer">footer</div>
绝对定位实现
<style>
* {
padding: 0;
margin: 0;
}
.header,
.footer {
width: 100%;
height: 200px;
background-color: blue;
}
.container {
position: relative;
padding: 0 100px;
}
.left {
width: 100px;
height: 300px;
background-color: pink;
position: absolute;
top: 0;
left: 0;
}
.main {
width: 100%;
height: 300px;
background-color: green;
}
.right {
width: 100px;
height: 300px;
background-color: pink;
position: absolute;
top: 0;
right: 0;
}
</style>
<div class="header">header</div>
<div class="container">
<div class="left col">left</div>
<div class="main col">main</div>
<div class="right col">right</div>
</div>
<div class="footer">footer</div>
总结
现在真正了解到圣杯布局、双飞翼布局和普通三列布局的思想了吗?虽然它们三者最终的效果可能一样,但是实际的思路,优化也都不一样,希望能对你有所帮助!!!!感谢支持
来源:juejin.cn/post/7405467437564428299