圣杯布局和双飞翼布局解决的问题是一样的,就是两边固定,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。
圣杯布局HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
/* box-sizing: border-box; */
}
#contain div{
float: left;
}
#contain{
width: 100%;
padding: 0 200px;
height: 600px;
}
#middle{
width: 100%;
height: 400px;
background: lightcoral;
}
#left{
width: 200px;
height: 200px;
position: relative;
margin-left: -100%;
left: -200px;
background: lightcyan;
}
#right{
width: 200px;
height: 200px;
float: left;
margin-right: -200px;
background: red;
}
</style>
</head>
<body>
<div id="contain">
<div id="middle"></div>
<div id="left"></div>
<div id="right">abc</div>
</div>
</body>
</html>
双飞翼代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
/* box-sizing: border-box; */
}
.container,.left,.right{
float: left;
}
.container{
width: 100%;
height: 400px;
/* padding: 0 200px; */
}
.middle{
height: 400px;
margin: 0 200px;
background: royalblue;
}
.left{
width: 200px;
height: 200px;
margin-left: -100%;
background: rebeccapurple;
}
.right{
width: 200px;
height: 100px;
margin-left: -200px;
background: #0c9;
}
</style>
</head>
<body>
<div class="container">
<div class="middle">asdas</div>
</div>
<div class="left">asd</div>
<div class="right">asd</div>
</body>
</html>
圣杯布局和双飞翼布局的优点和缺点网上都有很多文章,但是我个人接触这个布局的时候,最困难理解的就是margin负值的情况,许多文档都对这个margin负值的情况解释得不是很清楚,查了许多文章总结一下个人的理解。
首先一个盒子的真正的宽高等于内容的宽高+padding+border+margin,这里就引申出了标准盒模型以及怪异盒模型的概念。二者区别在于盒子宽高是否随padding和border的变化而变化,本文不讨论这个问题。直入主题了。
圣杯布局
#contain div{
float: left;
}
#contain{
width: 100%;
padding: 0 200px;
height: 600px;
}
#middle{
width: 100%;
height: 400px;
background: lightcoral;
}
#left{
width: 200px;
height: 200px;
background: skyblue;
}
#right{
width: 200px;
height: 200px;
background: red;
}
首先给父盒子contain一个左右padding200px,middle、left和right给上宽高和左浮动,此时的效果如下
两个margin和浮动的规律(通过搜集文章和自己试验确实如此,希望错了可以指出):
- 当元素的浮动方向和margin的方向相同时,该元素可以覆盖或远离上一个浮动元素
- 当元素的浮动方向和margin的方向相反时,该元素不能覆盖上一个浮动元素,最近只能紧贴上一个元素右边。
由于middle盒子宽度为100%,所以left和right都被挤到下面,通过计算公式
盒子的宽高等于内容的宽高+padding+border+margin
padding和border都不能为负值,所以我们只能通过margin来改变当前的布局
要想left盒子在middle行内放下的,只能盒子宽小于0的时候,当left盒子margin-left为-200的时候,left盒子总宽度为200+0+0-200=0,此时left盒子就能浮动上面了
此时效果就会这样
因此只要margin-left为100%的时候,他就会移到middle最左侧,因为middle宽度为100%。
此时要移到最左边只需要相对于自己定位,往左移动200即可移到父盒子的最左侧。
以上说的就是当元素的浮动方向和margin的方向相同时,该元素可以覆盖或远离上一个浮动元素的情况(上一个浮动的元素为middle)
下面就是元素浮动方向和margin方向相反时,结论:当元素的浮动方向和margin的方向相反时,该元素不能覆盖上一个浮动元素,最近只能紧贴上一个元素右边。
所以只需要设置right盒子margin-right:-200px,他就可以贴着middle元素的右边。
双飞翼布局原理也和圣杯差不多,套用两个结论在理解下就能明白了。
再来个例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.left{
width: 200px;
height: 200px;
float: left;
background: slateblue;
}
.right{
width: 200px;
height: 200px;
margin-right: 200px;
float: left;
background: palegoldenrod;
}
</style>
</head>
<body>
<div class="left">left</div>
<div class="right">right</div>
</body>
</html>
两个左浮动的盒子,此时无论怎么给right盒子margin-right的值,他都只会紧贴着left盒子。当给right盒子marin-left的时候,他是可以覆盖在left盒子上面的,由于图太多,弄动态图也麻烦,分享一下希望看到的伙伴可以自己尝试一下,分享下各自的心得,也欢迎指出和纠正我的错误。