首先谈一下什么是BFC?
BFC(Block formatting context)直译为“块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box(块)参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
BFC是如何布局的呢?
1、内部的Box会在垂直方向,一个接一个地放置。
2、Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(按照最大margin值设置)
3、每个元素的margin box的左边, 与包含块border box的左边相接触
4、BFC的区域不会与float box重叠。
5、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
6、计算BFC的高度时,浮动元素也参与计算
那么哪些元素和属性能触发BFC?
1、 根元素(html)
本身就是一个大的BFC ,遵循自上而下的排列
2、 float属性不为none
当添加 float:left;或者 float:right;的时候,可以让元素 变成一个独立的空间(BFC)
3、 position为absolute或fixed
4、display为inline-block, table-cell, table-caption, flex, inline-flex
5、overflow不为visible
overflow为 hidden, auto ,scroll,可以让元素生成一个BFC
BFC的应用
以下几个方面是常见的利用BFC解决问题
1、防止margin上下重叠
2、清除内部浮动
3、自适应两栏布局
下面分别用例子解释BFC的应用:
一、防止margin上下重叠
1.overflow:hidden触发BFC,解决子元素添加margin-top导致错误的添加到父元素上
<div class="box1">
<div class="content">
</div>
</div>
.box1{
width:200px;
height:200px;
background:green;
overflow:hidden;
}
.content{
width:100px;
height:100px;
background:red;
margin-top:50px;
}
未添加overflow:hidden;运行结果:
添加 overflow:hidden;运行结果:
2.BFC解决margin重叠问题,在同一个BFC里面发生重叠,所以变成两个BFC就不会出现重叠的问题
<div class="box2"></div>
<div class="box3"></div>
上面代码可以看出,box2,box3在同一个BFC里面,只要在同一个BFC里面就要遵循它的规则 ,所以要想解决这个问题,我们要把它变成两个BFC,那么如何做呢?
首先在box3的外面嵌套一个元素wrap,给wrap添加元素让wrap生成一个独立的BFC空间,html代码如下
<div class="box2"></div>
<div class="wrap">
<div class="box3"></div>
</div>
``
根据上文写的 **哪些元素和属性能触发BFC?**里面的几条分析如下:
(1)给wrap添加float属性
虽然能解决变成两个BFC,解决margin重复的问题,但是如果wrap下面还有元素的话(例如在wrap下面添加p标签),会受到浮动元素的影响跑到上面去。
CSS代码以及运行结果如下:
.box2{
width:200px;
height:200px;
background:#0f0;
margin-bottom:50px;
}
.wrap{
float:left;
}
.box3{
width:200px;
height:200px;
background:#00f;
margin-top:50px;
float: left;
}
因此不建议使用float解决这个问题
(2)给wrap添加overflow:hidden;
.wrap{
overflow:hidden;
}
不会影响下面的布局,运行结果如下
二、.BFC实现清除内部浮动
父元素高度设为auto,子元素添加浮动,子元素脱离文档流,导致父元素不能被撑开,那么如何才能解决父元素这个问题,让父元素显示高度,高度自适应,这个时候用万能清除法、固定高度、加空的div标签也可以,
还有一个方法就是给父元素添加overflow:hidden;把父元素变成一个BFC,这样就会遵循BFC原则了,而在上面总结的BFC原则中有一条计算BFC的高度时,浮动元素也参与计算,从而解决这个问题。
代码如下:
<div class="box">
<div class="content1"></div>
<div class="content2"></div>
</div>
.box{
width:600px;
height: auto;
border:2px solid #f00;
margin:30px auto;
overflow:hidden;
}
.content1{
height:200px;
width: 200px;
background:#f0f;
float:left;
}
.content2{
height:200px;
width: 350px;
background:#0ff;
float: right;
}
运行截图如下
三、自适应两栏布局
1.两栏(左固右自适应,不产生滚动条)
<div class="left">1111</div>
<div class="right">2222</div>
<style type="text/css">
*{margin:0;padding:0; }
html,body{height:100%;}
.left{
width: 200px;
height:100%;
background:#f00;
float:left;
}
.right{
height:100%;
background:#0f0;
overflow:hidden;
}
</style>
运行结果如下:
解释:left宽度固定,要使right不添加宽度,实现宽度自适应,
让left和right在一排显示,给left添加float,left浮在上面,right被压在下面,解决办法
(1)浮动:给right添加浮动
不可行
原因:添加浮动的right,right的宽度是被内容撑起来(块状元素添加浮动之后,宽度与内容有关了),不能宽度自适应
(2)给right添加overflow:hidden;可实现宽度自适应
要想产生滚动条用overflow:auto;
2.双飞翼布局(左右宽度固定,中间宽度自适应)
overflow:hidden;虽然能解决两栏问题,但是解决不了双飞翼问题,解决双飞翼问题可以通过
(1)改变结构
先将左右浮动的div放在前面,左后写center的布局,在将overflow:hiddden;添加在center上,保证内容不被left和right覆盖。
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
.left{
width:200px;
height:300px;
background: #f00;
float:left;
}
.right{
width:200px;
height:300px;
background: #0f0;
float:right;
}
.center{
height:300px;
background:#f0f;
overflow:hidden;
}
运行结果:
(2)定位
给center定位,如果有父元素,就相对于父元素定位
如果没有父元素,就相对于大的窗口定位
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
.left{
width:200px;
background: #f00;
float:left;
}
.right{
width:200px;
background: #0f0;
float:right;
}
.center{
background:#f0f;
position: absolute;
left:200px;
right:200px;
}
运行结果:
勤奋积累,善于总结(逆战班 )