背熟以下口诀,BFC轻松给你

529 阅读5分钟

BFC是什么?

BFC(block formatting context)块级格式化上下文,之前经常听说BFC,也一直一知半解,觉得其很是神秘。最近找工作,于是认真学习了一下,发现其实并没有想象那么难以理解。简而言之,BFC是页面上隔离的一个独立容器,它不会与容器外的其他元素互相影响。举个例子,你可以理解页面的根元素<html>就是一个BFC,它里面的子元素的定位等只与<html>这个根元素有关,而与其他的页面无关。当元素是一个BFC时,它会有自己的一套页面渲染或者计算规则。

BFC的创建条件

首先,我们来学习一下什么情况下会创建一个BFC。

  • 根元素
  • 元素浮动
  • 元素position为absolute,fixed
  • 元素overflow值不为visible
  • 元素display的值为inline-block,table-cell,table-caption
  • 等等...(详细可以参见块格式化上下文

BFC的渲染规则口诀

当一个元素形成一个BFC时,它可以帮助我们解决很多样式问题。在介绍BFC大法之前,你需要记住以下口诀:

  • 当一个元素满足了xxx条件,该元素就成为一个BFC
  • 当一个元素是一个BFC,则会满足一些渲染规则

BFC渲染规则

在背熟以上口诀后,我们就来造轮子举例,细细说一说BFC的渲染规则,下面请看重点

1. BFC在计算自身高度时会包含内部的浮动元素

在使用浮动样式时,常常会造成父级容器的高度塌陷,例如:

<style>
    .parent {
        border: 1px solid green;
        width: 600px;
    }

    .child {
        height: 100px;
        width: 400px;
        background: yellow;
    }

    .float {
        float: left;
        height: 100px;
        width: 400px;
        background: orange;
    }
</style>

<div class="parent">
    <div class="child"></div>
    <div class="float"></div>
</div>

上图可以看到,parent在计算自身高度时,会忽略掉浮动元素的高度,造成parent元素的高度塌陷。
当我们给.parent元素加上overflow:auto时,满足上面条件4,因此parent元素会形成一个BFC,在计算自身高度时会包含内部的浮动元素

.parent{
   border: 1px solid green;
   width: 600px;
   overflow:auto; 
}

2. BFC不会与其他的兄弟元素发生关系,因此可以防止元素间的margin重叠

我们知道,内容在垂直方向上两个相邻div的margin会发生重叠,会以两个元素margin中最大的那个作为两个元素间的实际margin,这个时候就造成了margin垂直方向上的重叠。举例如下:

<style>    
.child1{        
    height: 100px;        
    width: 300px;        
    background: yellow;        
    margin: 20px;    
}    
.child2{        
    height: 100px;        
    width: 300px;        
    background: orange;        
    margin: 20px;    
}
</style>

<div>    
    <div class="child1"></div>    
    <div class="child2"></div>
</div>

结果出来的布局效果却是

child1和child2都同时设置margin:20px,由于相邻元素的margin垂直方向上会重叠,因此两个元素只有20px的margin。 为了防止margin的重叠,我们可以在child2元素外面包裹一层div,设置其overflow:auto,使之成为一个BFC,这样BFC便不会与外界相邻元素发生关系,有效解决了该问题。

<style>
    .child1{
        height: 100px;
        width: 300px;
        background: yellow;
        margin: 20px;
    }
    .child2{
        height: 100px;
        width: 300px;
        background: orange;
        margin: 20px;
    }
    .bfc{
        overflow: auto;
    }
</style>

<div>
    <div class="child1"></div>
    <div class="bfc">
        <div class="child2"></div>
    </div>
</div>

设置以上样式之后,.bfc形成了一个BFC,不会与外界相邻元素发生关系。

从结果图中我们可以看到,child1和child2之间有40px的间距。

3. BFC不会与浮动元素重叠,因此可以简单的实现双栏布局

在页面布局中,我们常常会用到左侧菜单栏,右侧主体内容的双栏布局。在实践中,我们常采用以下的方式实现。即左侧浮动,右侧margin-left:左侧浮动的宽度

用以上样式便可以轻松实现两栏布局,就像这样,左边侧边栏,右侧主体内容。

除此方法之外,如果结合BFC的思想,一个BFC不会与兄弟元素发生关系。那么,如果当这个兄弟元素为浮动元素时,则为BFC元素区域不会与浮动元素发生重叠。在上面的实现代码上,将right中的margin-left删除,其效果图为
可以看到右侧的黄色元素直接从父级的最左侧开始渲染,与蓝色的左侧元素重合,其因为浮动元素时会脱离文档流的。这个时候设置.right元素的overflow:auto,使其成为一个BFC,这样它自己占有的区域不会和浮动元素发生重叠,就可以通过BFC的渲染规则轻松的实现两栏布局了。

<style>        
    .body-wrap{            
        height: 100px;        
    }        
    .left{            
        float:left;            
        width: 200px;            
        height: 100%;            
        background: blue;            
        opacity: 0.5;        
    }        
    .right{            
        height: 100%;            
        overflow:auto;           
        background: yellow;        
    }    
</style>

<div class="body-wrap">        
    <div class="left"></div>        
    <div class="right"></div>   
</div>

效果如下:

可以看到实现效果与使用margin-left无二。

4. BFC内的浮动不会影响到BFC外部的元素,实际应用为清除浮动
<style>        
    .parent{            
        overflow:auto;            
        width: 600px;        
    }        
    .float{            
        float:left;            
        height:100px;            
        width: 100%;        
    }        
    .child1{             
        background: orange;         
   }    
    .child2{            
        background: yellow;        
    }    
</style>

<div class="parent">        
    <div class="child1 float"></div>        
    <div class="child2 float"></div>    
</div>

可以设置.parent元素为overflow:auto,为一个BFC,采用这种方式可以清除浮动。但是对于清除浮动方法来说,这种方式在对于一些应用性样式上存在一定局限性,所以用得较少。
看了上面四个例子,是不是觉得BFC好像也没有那么难以理解了呢,大家主要记住一句话,当一个元素拥有某些样式设置时如overflow:auto等会使该元素成为一个BFC,当一个元素形成BFC时,会有自己的一套渲染规则,我们可以使用这些规则解决样式应用中的一些实际问题。

参考

学习BFC
MDN Web docx

以上,有写的不对的地方请大家指正、探讨。