Skip to main content
  1. Posts/

大白话版:什么是BFC

·2 分钟

什么是BFC #

BFC:全称Bloc Formatting Context,中文就是块级格式上下文。 它是W3C CSS2.1规范中的一个概念,决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用。

通俗点就是,它对元素的布局会产生影响。BFC提供了一个独立的环境(空间),HTML在这个环境中会按照一定的规则进行布局。

BFC对布局的影响 #

也就是BFC规则:

  • BFC内部的块元素会在垂直方向一个接一个的排列
  • 处于同一个BFC内的元素外边距会重叠
  • 计算BFC高度时,它包含的所有元素都要算进去,连浮动元素也算
  • BFC容器内的元素不受容器外部元素的影响,外部元素也不受BFC内部元素影响
  • 外部的浮动元素不会叠加到BFC上 下面用几个例子解释一下这些规则吧。

BFC中的常规流 #

BFC常规流

<style  type="text/css">
    .container {
        width: 500px;
        height: 500px;
        background-color: black;
        overflow: hidden;
    }
    .item {
        width: 100px;
        height: 100px;
        margin: 10px;
        background-color: red;
    }
</style>
<body>
    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
</body>

container是一个BFC容器,里面的item默认就是按照从上到下排列的。

外边距重叠 #

BFC常规流

.item {
    width: 100px;
    height: 100px;
    margin: 10px;
    background-color: red;
}
.item:last-child {
    margin-top: 20px;
}

可以看出,第二个item距离第一个item的外边距是10px,距离第三个item是20px,但其实三个item都设置了margin,因为处于同一个BFC中,所以元素间的外边距取最大值,而不是相加后的值。

BFC的高度 #

<style  type="text/css">
    .container {
        width: 500px;
        background-color: black;
        /* overflow: hidden; */
    }
    .item {
        width: 100px;
        height: 100px;
        margin: 10px;
        float: left;
        background-color: red;
    }
</style>

<body>
    <div class="container">
        <div class="item"></div>
    </div>
</body>

我们不给容器设置高度,子元素设置一个float: left属性,最终显示的效果是这样

BFC常规流
由于子元素脱离文档流造成容器高度坍塌,height: 0所以背景色没有显示,我们把注释掉的overflow: hidden;属性加回来,容器变成了BFC,背景色就显示出来了
BFC常规流
这就是为什么说计算BFC的高度需要考虑所有的元素,包括浮动元素。

BFC不受外部元素影响 #

前面提到在同一个BFC里,元素之间的外边距会重叠,那如果把另一个元素变成一个BFC的话,会是什么效果呢?

<style  type="text/css">
    .container {
        width: 500px;
        background-color: black;
        overflow: hidden;
    }
    .item {
        width: 100px;
        height: 100px;
        margin: 10px;
        background-color: red;
    }
    .item:last-child {
        display: inline-block;
        margin-top: 20px;
    }
</style>
<body>
    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
    </div>
</body>

BFC常规流
第二个item变成了一个BFC,并且margin-top设为了20px,两个元素之间的边距变成了30px。

浮动元素不会叠加到BFC上 #

<style  type="text/css">
    .container {
        width: 400px;
        background-color: black;
    }
    .item {
        width: 100px;
        height: 100px;
    }
    .item:first-child {
        float: left;
        background-color: red;
    }
    .item:last-child {
        width: 300px;
        background-color: green;
        /* display: flex; */
    }
</style>
<body>
    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
    </div>
</body>

子元素item进行左右布局,一个设置为float元素,一个固定宽度为300px,显示效果如下图

浮动元素
浮动元素和另一个元素重叠在一起了。

现在我们把第二个元素被注释掉的display: flex;属性加回来,让它变成BFC再看下效果

浮动元素和BFC
两个元素相邻排列,谁也没妨碍谁。

BFC触发条件 #

上面的例子已经有提到几个触发属性了:

  • 根元素或其它包含它的元素
  • 内联块元素:具有display : inline-block;属性的元素
  • 具有overflow属性,且值不为visible的块元素
  • 弹性盒元素:display属性的值为flexinline-flex
  • 绝对定位元素:pisition属性值为absolutefixed
  • 浮动元素:具有float属性,且值不为none
  • 表格单元格:display: table-cell
  • 表格标题:display: table-caption
  • display: flow-root
  • column-span: all