前言
有时候觉得对浮动布局,定位这些思考得其实还不够深入。
网上的说法很多,它们很多掺杂各种浏览器兼容或者一些清除浮动等等的hack。但是我觉得还是应该从简入深,理解一下它的本质。
两列布局
所谓的两列布局,首先是左边栏是定宽,右边主栏是自适应的。
一般看到自适应我们可很容易想到就是百分数,浮动布局。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Two Column</title>
<style type="text/css">
.container{
width:100%;
margin:0 auto;
}
.left{
width:200px;
background: red;
height: 300px;
}
.main{
width: 100%;
background: blue;
height: 300px;
}
</style>
</head>
<body>
<div class="container">
<div class="left"></div>
<div class="main"></div>
</div>
</body>
</html>
为什么要浮动呢?
首先,如果直接把两个div,也就是块级元素放到页面上,它们显然是会换行显示,因为display:block的元素它的两边都会换行。
所以得到的是这样的:
我们为了让下边的元素自适应可以设置两个元素都浮动,但是设置了浮动,因为你把主栏的div设置了100%显示,他会霸占了整个包含块的宽度,这时它会下浮。所以其实和上面那张图是一样的效果。
问题: 怎么让下面的div上浮上来?
Solution One
我的第一种做法是设置主栏div为负外边距。
负外边距,这个东西看上去很玄。。
其实我们这么想,现在我下面的div是要霸占包含块的所有宽度,但是上面有一个div已经占据了一部分的宽度,所以这个div无法占有全部的宽度,所以为了达到这个目的,它会下浮,看上去就像被上面的div弹下来的感觉。
制造假象
我们有没有可能制造一种假象,让这个div认为它霸占了全部的宽度呢? 其实就是设置它的负外边距为上方div的宽度。
我们发现它已经覆盖了上方的div了。因为一个元素设置了负外边距,就好像把自己的尺寸减小了,没错,我说的是盒子模型,所以此时设置负外边距可以让它满足width:100%的要求。
加上relative定位
我们现在缺少的就是离开左边的距离,使用left来设置200px。
其实float和relative一起用是可以的,它就相当于你先浮动了这个元素然后再去移动它往某个方向一段距离。
.container{
width:100%;
margin:0 auto;
}
.left{
width:200px;
/*margin-left: -200px;*/
background: red;
height: 300px;
float:left;
}
.main{
margin-left: -200px;
position: relative;
left:200px;
width: 100%;
background: blue;
height: 300px;
float:left;
}
结果:
Solution Two
其实我们还可以对包含框元素设置一个margin-left。
让它腾出一部分空间给浮动元素。
.container{
width:100%;
margin:0 auto;
margin-left: 200px;
}
.left{
width:200px;
background: red;
height: 300px;
float:left;
}
.main{
width: 100%;
background: blue;
height: 300px;
float:left;
}
左边腾出了空间。
显然,后面我们还是利用负外边距这个“黑魔法”,但实际上我们只要设置红色div的外边距为负即可。
浮动元素一般是浮动到紧紧挨在包含块的内容边界上,即padding-box。
所以你可以设置负外边距,让这个浮动元素左移到左边的margin空间。这样它就相当于离开了这个包含块。
然后下方的div也会因此上浮上来,因为在它看来,上面的空间已经没有浮动元素了,它可以上浮上来占据所有的空间!
.container{
width:100%;
margin:0 auto;
margin-left: 200px;
}
.left{
margin-left: -200px;
width:200px;
background: red;
height: 300px;
float:left;
}
.main{
width: 100%;
background: blue;
height: 300px;
float:left;
}
左栏不定宽
改成百分数即可,此时连左边栏也是根据包含块的宽度来适应
浏览器窗口大小了
.container{
width:100%;
margin:0 auto;
margin-left:25%;
}
.left{
margin-left: -25%;
width:25%;
background: red;
height: 300px;
float:left;
}
.main{
width: 100%;
background: blue;
height: 300px;
float:left;
}