BFC概念
BFC(Block formatting context)直译为“块级格式化上下文”,只有块级的盒子参与,内部规定了块级盒子如何布局。
BFC是一个独立的布局环境,其中的元素布局是不受外界的影响。
display属性为block、table、list-item的元素默认会产生BFC。也可以手动创建,如果将一个div(默认为块级元素,即本身拥有BFC)设置为inline-block,会产生一个新的BFC。
如何创建BFC
- float属性不为none
- position属性为absolute或fixed
- display为inline-box、flex、inline-flex、table-cell
- overflow不为visible
BFC布局特性
- 在BFC中,盒子从顶端开始垂直往下排列
- 盒子垂直方向的间距由margin决定,属于同一个BFC的两个相邻的盒子margin会发生重叠
- 在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左内边缘(border-left)
- BFC的区域不会与浮动盒子产生交集,而是紧贴浮动边缘
- 在计算BFC的高度时,也会检测浮动或定位的盒子高度
BFC的作用
- 清除浮动 
 只要把父元素设置为BFC,就可以清除子元素的浮动了,如:常使用- overflow:hidden- 1 
 2
 3- <div> 
 <p>1</p>
 </div>- 1 
 2
 3
 4
 5
 6- div{} 
 p {
 width: 200px;
 line-height: 100px;
 text-align: center;
 }- 我们可以给div设置以下这些样式 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16- div{ 
 /*推荐第一种*/
 overflow: hidden;
 overflow: auto;
 display: flex;
 /* 可以解决p的浮动问题,但同时增加了div自己的浮动问题 */
 float: left;
 /* 可以解决p的浮动问题,但是同时让div没有宽度,只是被p给撑起来了 */
 display: inline-block;
 display: table-cell;
 display: inline-flex;
 position: absolute;
 position: fixed;
 }
- 解决外边距合并问题 
 只要创建不属于同一个BFC,外边距就不会发生合并,如:- 1 
 2- <p>1</p> 
 <p class="p2">2</p>- 1 
 2
 3
 4
 5
 6
 7- p { 
 width: 200px;
 line-height: 100px;
 text-align: center;
 background-color: #f00;
 margin: 30px;
 }- 有两个p(块级元素,本身拥有同一个BFC),都设置 - marign时,默认p1的- marign-bottom和p2的- margin-top会发生合并,只表现出一个30px的间距。 
 如何解决呢?可以让p2产生一个新的BFC,只要不p1、p2不属于同一个BFC,- margin就不会发生合并。- 1 
 2
 3
 4
 5
 6
 7- .p2{ 
 float: left;
 display: inline-block;
 display: inline-flex;
 position: absolute;
 position: fixed;
 }- 以上这些属性都可以直接作用于某个盒子本身,然后产生一个新的BFC。当然也可以有更多的办法: - 1 
 2
 3
 4- <p>1</p> 
 <div>
 <p>2</p>
 </div>- 使用div包裹p2,然后给div这个父级设置样式,这个时候就有了更多的选择,任选一种即可。 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- div{ 
 float: left;
 display: inline-block;
 display: inline-flex;
 position: absolute;
 position: fixed;
 /* 除了上面这些,还可添加这些作用于父级的样式 */
 overflow: hidden;
 overflow: auto;
 display: flex;
 display: table-cell;
 }
- 自适应两列布局 
 根据特性3: 每一个盒子的左外边缘(marigin)会触碰容器的左内边缘(border-left),即使是浮动元素。- 1 
 2- <div class="left">LEFT</div> 
 <div class="right">RIGHT</div>- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20- body{ 
 border: 5px solid #f00;
 }
 .left {
 width: 100px;
 height: 150px;
 float: left;
 background: #0f0;
 text-align: center;
 line-height: 150px;
 font-size: 20px;
 margin: 5px;
 }
 .right {
 height: 300px;
 background: #00f;
 text-align: center;
 line-height: 300px;
 font-size: 40px;
 }- 从下图可以看出:left的margin-left外边缘(蓝色margin 5px左侧)和父级容器(body)的border-left(红色border 5px内侧)内边相触碰。  - 再根据特性4:BFC的区域不会与浮动盒子产生交集,而是紧贴浮动边缘。 
 让right单独成一个BFC,添加样式:- 1 
 2
 3- .right{ 
 overflow: hidden;
 }- 这样就实现两列布局了,并且right布局可以自适应。 