什么是BFC、有哪些具体应用?

694 阅读3分钟

前言

BFC 是 Block Formatting Context 的简写:块级格式化上下文

w3c 官方解释为:BFC 决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用,当涉及到可视化布局时,BFC 提供了一个环境,HTML 在这个环境中按照一定的规则进行布局。

简单来说,BFC是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局

如何创建 BFC

  • 根元素或其他包含它的元素
  • 浮动:float: 不为 none
  • 绝对定位元素:position: absolute / fixed
  • 行内块级元素:display: inline-block
  • 表格单元格:display: table-cell
  • overflow 的值 不为 visible 的元素
  • 弹性盒子:display: flex / inline-flex

BFC 的效果

  • BFC 是一个块级元素,在垂直方向一个接一个排列
  • 垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻标签外边距会发生重叠
  • 计算 BFC 高度时会考虑所包含的所有元素,也包括浮动元素(解决元素高度塌陷问题)
  • 阻止普通文档流元素被浮动元素覆盖(浮动盒区域不叠加到 BFC 上)
  • 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明 BFC 中子元素不会超出他的包含块,而 position 为a bsolute 的元素可以超出他的包含块边界)

具体应用

初始 demo

* {
    margin: 0;
    padding: 0;
}

.left{
    background: yellow; // 黄色
    border: 2px solid red;
    opacity: 0.5;
    width: 200px;
    height: 200px;
    float: left;
}

.right{
    background: green; // 绿色
    border: 2px solid gold;
    opacity: 0.5;
    width:400px;
    min-height: 100px;
}

.box{
    background: #999;
    height: 100%;
    margin-left: 10px;
}

<div class='box'>
    <div class='left' />
    <div class='right' />
</div>

image.png

由上图可以看出,黄色框向左浮动,使它脱离了原本的位置,由此绿色框被定位到灰色父元素,并与浮动元素重叠。 同时,由于父元素灰色框没有创建 BFC,由此计算高度时不会考虑灰色框的区域,也就是常见的 高度坍塌 问题

应用一:防止高度坍塌

给灰色框创建一个新的 BFC 后,高度计算时会包括浮动元素(灰色框高度变化)

.BFC {
    overflow: hiddle;
}

<div className='box BFC'>
    <div className='left' />
    <div className='right' />
</div>

image.png

应用二:阻止与浮动元素重叠

  • 如下例:由于绿色框没有创建 BFC,其中的白色块受到黄色框(浮动元素)的影响,被挤到右边的同时超出了绿色框的范围。

<style>
    .little{
        background: #fff;
        width: 50px;
        height: 50px;
        margin: 10px;
        float: left;
    }
</style>

<div className='box BFC'>
    <div className='left' />
    <div className='right'>
        <div className='little' />
        <div className='little' />
        <div className='little' />
    </div>
</div>

image.png

  • 给绿色框创建 BFC 后,则并不会与黄色框发生重叠,同时由于 BFC 的隔离作用(一个独立容器),白色块不会受到黄色浮动框的影响(也说明其 每个元素的margin box的左边,与容器块border box的左边相接触
  • 注意:触发 BFC 不能阻止其他形式的脱离文档流的元素覆盖正常流元素(比如绝对定位元素)
<div className='right BFC'>
    ...
</div>

image.png

应用三:阻止 margin 合并

阻止相邻元素的 margin 合并

给两个框分别添加 margin,由图可知相邻的 margin 会被合并


<style>
    .right {
        margin: 20px;
        ...
    }
    .left {
        margin: 20px;
        ...
    }
</style>

<div className="box BFC">
    <div className="left" />
    <div className="right" />
</div>

image.png

  • 给其中一个元素(也可以两个元素)设置 BFC,可以阻止 margin 的合并
  • 注意:块级元素会默认铺满一行
<div className="box BFC">
    <div className="BFC">
        <div className="left" />
    </div>
    <div className="right" />
</div>

image.png

应用四:自适应两栏布局

  • 利用 BFC 不会与浮动元素重叠的特性,同时由于块级元素默认铺满整行,就可以实现两栏自适应布局
<style>
    .left {
    // 保持左浮动
    }
    .right {
    // 删除 width
    }
</style>

<div className="box BFC">
    <div className="left" />
    <div className="right BFC" />
</div>

image.png

参考