块级格式化上下文BFC(Block Formatting Context)

561 阅读2分钟

如何理解BFC

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

通俗来讲:它是一块独立的渲染区域, 不同的BFC区域,他们在渲染的时候互不干扰。创建BFC的元素,隔绝了它内部和外部的连续,内部的渲染不会影响到外部的渲染。

BFC作为一块独立的渲染区域,它规定了该区域中,常规流块盒的布局。

  • 常规流块盒在水平方向上,必须撑满包含块
  • 常规流块盒在包含块的垂直方向上依次摆放
  • 常规流块盒若外边距无缝相邻,则进行外边距合并
  • 常规流块盒的自动高度和摆放位置,无视浮动元素

无标题-2023-04-05-1446.png

如何创建一个BFC

BFC是由某个HTML元素创建,以下元素会在其内部创建BFC区域:

  • 根元素:意味着,<html>元素会创建BFC区域,覆盖了网页中所有的元素。
  • 浮动和绝对定位元素。
  • overflow 不等于 visible 的元素。
  • display 属性为 inline-block, flex, table-cell的元素。
  • 更多创建方法...

BFC可以解决那些常见的布局问题

1. 解决子元素浮动带来的高度坍塌问题

  • 创建BFC的元素,它的自动高度需要计算浮动元素。

创建BFC前: 父元素 div.box 的高度不会被浮动的字元素撑开,高度为 0;

<style>
    .box{
        background-color: skyblue;
        /* BFC */
        /* overflow: hidden; */
    }
    .item{
        float: left;
        width: 100px;
        height: 100px;
        margin: 20px;
        background-color:red;
    }
</style>
 <div class="box">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

WX20230405-152351@2x.png

创建BFC之后: 父元素 div.box 的高度被浮动的字元素撑开。

<style>
    .box{
        background-color: skyblue;
        /* BFC */
        overflow: hidden;
    }
    .item{
        float: left;
        width: 100px;
        height: 100px;
        margin: 20px;
        background-color:red;
    }
</style>
 <div class="box">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

WX20230405-152416@2x.png

2. 两栏布局

  • 创建BFC元素,他的边框盒不会与浮动元素重叠。

创建BFC前: div.container 元素的渲染区域会覆盖浮动元素div.left的渲染区域。

<style>
    .left{
        float: left;
        width: 100px;
        height: 200px;
        background-color: red;
    }
    .container{
        background-color: skyblue;
        height: 300px;
        /* bfc */
        /* overflow: hidden; */
    }
</style>
<body>
    <div class="left">left</div>
    <div class="container">container</div>
</body>

WX20230405-153336@2x.png

创建BFC之后: div.container 元素的渲染区域不会覆盖浮动元素div.left的渲染区域。同时可以通过设置 div.left 元素的 margin-right 的值来调整两个元素之间的间距。

<style>
    .left{
        float: left;
        width: 100px;
        height: 200px;
        background-color: red;
    }
    .container{
        background-color: skyblue;
        height: 300px;
        /* bfc */
        overflow: hidden;
    }
</style>
<body>
    <div class="left">left</div>
    <div class="container">container</div>
</body>

WX20230405-153356@2x.png

3. 相邻元素Margin边距重叠问题

  • 创建BFC的元素,不会和它的子元素进行外边距合并。(不同的BFC区域中的字元素不会进行外边距合并)

创建BFC之前: 子元素div.innermargin-top 与父元素 div.containermargin-top 重合。

<style>
    .container {
        margin-top: 20px;
        height: 200px;
        background-color: red;
    }
    .inner{
        margin-top: 30px;
        height: 100px;
        background-color: skyblue;
    }
</style>
<body>
    <div class="container">
        <div class="inner"></div>
    </div>
</body>

WX20230405-154820@2x.png

创建BFC之后: 子元素div.innermargin-top 与父元素 div.containermargin-top 不会重合。

<style>
    .container {
        margin-top: 20px;
        height: 200px;
        background-color: red;
        /* bfc */
        overflow: hidden;
    }
    .inner{
        margin-top: 30px;
        height: 100px;
        background-color: skyblue;
    }
</style>
<body>
    <div class="container">
        <div class="inner"></div>
    </div>
</body>

WX20230405-154856@2x.png

参考文章

MDN:块格式化上下文 面试官:请说说什么是BFC?大白话讲清楚