想必各位前端对于双飞翼和圣杯布局可谓是咬牙切齿,背面试题的时候,首先这样、其次这样,最后那样。一套连招下来,这不是很简单吗,这必不可能难倒我,看我到时一套连招让面试官直接大呼,牛逼!
但是,哈哈哈。当面试官问到,实现一个双飞翼圣杯布局呗。秒怂,支支吾吾,刚开始背的面试题直接变成天书,这些都是什么东西,完蛋,那套连招是什么?然后就给面试官一个微笑直接破防,最后回去等通知。
我为什么这么清楚,因为我也受这个背面试题的影响。答应我,好好看下去!直接一套连招让你行起来!
原因
先说说为什么面试官为什么会这么热衷于考双飞翼圣杯的面试题?
抛开css本身的知识点大多数都是背诵和一些重点都是动画布局,并不像js方面有很多可以拿出来考的知识点,然后 考圣杯双飞翼布局,可以综合的考察到面试者是否能完成一些正常的布局,以及对于布局的一些细节是否掌握。
这里仅此是用浮动布局来实现双飞翼圣杯布局,后面会再出用其他的布局来实现这个布局,但是本质还是一样的。
考点
- margin负值的原理
- clear清除浮动的方法
- 相对定位与绝对定位
原理
其实会有一部分人好奇什么是双飞翼圣杯布局?他们有什么不同点等不太清楚,一开始,在看到双飞翼圣杯布局,我很疑惑这两个到底是有什么不同,不都是三列布局吗?怎么整出两个不同的名字,请记住他们的不同点!下面理解起来会很简单的。
共同点:
- 内容区都是三列布局
- 中间的区域都是随着页面的宽度变大,两边的内容固定大小
不同点:
- 双飞翼是中间内容用一个盒子包裹起来的,然后用margin给两侧留出位置,而圣杯是外面套了个大盒子,设置大盒子的padding来给两侧留出位置
- 圣杯布局的左侧内容是通过相对定位来布局的
- 双飞翼布局的右侧内容是通过margin-left布局
口嗨原理:
- 双飞翼布局:
给中间内容套一层盒子,最外层的盒子宽度为百分之百,并且放在左右两侧盒子的前面(因为浏览器优先渲染放在前面的div,中间的内容普遍需要优先展示的)
给三列的盒子设置左浮动
中间盒子里面内容div设置margin的左右边距为左右内容盒子的宽度,给两侧的盒子留个固定的位置,然后清楚浮动
给右侧盒子设置margin-left为负的自身宽度,这样就可以挤上去
给左侧盒子设置margin-left为负的中间盒子的宽度,这样就覆盖上中间盒子的开始,因为里面内容盒子设置了margin这样就到达最左侧的位置
- 圣杯布局
前面和双飞翼布局一样,但是因为外面是有一层大盒子包裹三列盒子的,所以直接用大盒子设置padding,这样就可以给两侧留出位置,然后左侧的盒子通过margin-left(中间盒子的宽度)和相对定位的right(自身的宽度)到达最左侧的位置因为一开始是用padding来留出左右的位置,所以在外边距的负值将左侧的盒子覆盖中间盒子开头,只能用相对定位把它移到padding的地方 ,然后右侧的盒子就可以直接用margin-right为自己的负值放到上面的右侧位置。
最后,不要忘记给包裹三列盒子设置清楚浮动的代码了,可以通过overflow:hidden,不然大盒子因为没有高度会出现盒子塌陷的现象
圣杯布局的代码
因为圣杯布局和双飞翼的布局类似,所以就贴个复杂的圣杯布局的代码,可以试着写双飞翼的布局来学习下。
结构
<body>
<header></header>
<section>
<div class="main column"></div>
<div class="left column"></div>
<div class="right column"></div>
</section>
<footer></footer>
</body>
样式
* {
margin: 0;
padding: 0;
}
header {
height: 200px;
background-color: brown;
}
footer {
height: 200px;
background-color: brown;
}
section {
overflow: hidden;
padding: 0 200px 0 200px;
}
.main {
width: 100%;
height: 300px;
background-color: black;
}
.left {
position: relative;
right: 200px;
width: 200px;
height: 300px;
margin-left: -100%;
background-color: blueviolet;
}
.right {
width: 200px;
height: 300px;
margin-right: -200px;
background-color: cadetblue;
}
.column {
float: left;
}
更新
写完后有些点没写清楚,再讲点有些我认为对学习双飞翼和圣杯布局有用的知识点
- 为什么在双飞翼布局中右侧使用margin-left负值,而圣杯布局使用margin-right负值?
我的思考是,因为margin负值中,如果是浮动元素使用了margin负值,当浮动方向和外边距相同的时候是元素向浮动的地方位移,如果浮动的方向和外边距负值的方向不同的话,比如说我是左浮动,但是我设置margin-right:-100px,那么我左边的元素会向右位移100px来盖住我,那么就回到当前这个问题,因为双飞翼中是用margin给左右两列空出位置,如果右侧的设置右外边距,那么中间内容就会盖住右侧的内容,所以得用margin-left,而圣杯布局,因为使用padding来为两侧留位置,所以可以让中间内容盖住右侧内容的。
总结
双飞翼布局是淘宝团队为了优化圣杯布局出现的,两者都是三列布局,中间内容是自适应的,但是圣杯布局较为复杂,通过使用padding来为左右两侧留位置,然后左侧的内容通过margin-left负值和相对定位移到最左边,,然后右侧内容通过margin-right负值移到最右侧,但双飞翼布局不同的是通过给中间内容再加一个内容盒子,通过中间盒子的外边距给左右两侧留了位置,然后左侧盒子直接margin-left负值就可以到最左边,不需要相对定位,但右侧的内容则需要margin-left位移到最右边,这其中得注意给父元素清楚浮动,通过overflow:hidden,以及还需要给中间盒子指定最小宽度,以免造成浏览器拉到小于左右盒子的宽度时,布局错乱。