块级格式化上下文-BFC

269 阅读4分钟

BFC 是一个包含所有其内部子元素的矩形区域,它决定了这些子元素如何定位和排列。每个元素在其父容器中形成自己的格式化上下文,而 BFC 则是其中的一种类型,专门用于块级元素。 BFC 是 Web 页面中一个独立的布局环境,其中的元素按照特定规则进行布局,并且不会影响到上下文之外的元素。

BFC 是布局中的一个迷你布局

你可以将 BFC 看作是页面内的一个迷你布局。创建了一个新的BFC时,它实际上是在告诉浏览器:“这个元素内的所有内容都应该被包含在这个元素内。

当我们进行一些设置时就会开启一个BFC,想象 BFC 就像一个独立的容器,就像在一个房间里

  • 房间里发生的事情不会影响到外面

  • 外面发生的事情也不会影响到房间里

  • 房间里的东西都按照特定的规则来摆放

我们来说说BFC的作用吧

BFC的作用

1.防止 margin 重叠。

当处于同一BFC的块级元素会发生上下外边界重叠。可以看看小编之前介绍外边界重叠的文章(外边距重叠)- 掘金。 而我们可以通过开启一个BFC来解决外边距重叠的问题。

本质上还是这句话:创建了一个新的BFC时,它实际上是在告诉浏览器:“这个元素内的所有内容都应该被包含在这个元素内。”所以我们的外边距被包裹到盒子以内了。

    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .box1{
            width: 100px;
            height: 100px;
            background-color: red;
            margin: 20px;
        }
        .box2{
            margin: 20px;/*box2发生了坍塌*/
            width: 100px;
            height: 100px;
            background-color: green;
        }
    </style>
</head>
<body>
        <div class="box2" ></div>
        <div class="box1" ></div>
</body>
image.png 可以看到两个元素外边距发生了重叠现象,我们来试试给一个元素开启一个BFC。
.box1{
         overflow: hidden;
      }

但是外边距还是重叠着的,不是说开启了BFC可以防止元素重叠吗?小编你个骗子,狗头给我拿过来!!! 啊哈哈哈

注意了,我们给一个容器开启了BFC,他的作用范围是在容器内部,作用范围如下:

BFC容器:
└── div (overflow: hidden)
    │── BFC作用范围开始
    └── 子元素的margin被包含在这里
    │── BFC作用范围结束

也就是说我们需要用一个容器将一个div盒子包裹起来,这样外边距就在作用范围中了

<style>
  .father{
            overflow: hidden;
        }
</style>
</head>
<body>
        <div class="box2" ></div>
        <div class="father">
        <div class="box1" ></div>
    </div>

父子元素同样如此,当父子盒子发生外边距重叠时,给父盒子开启一个BFC即可防止重叠(“这个元素内的所有内容都应该被包含在这个元素内。”)

2.计算浮动元素盒子占位(清除浮动):

我们都知道,当给一个元素开启浮动之后,他会脱离文档流。举个例子

    <style>
        .parent { //父盒子样式
    background-color: red;
  }
  .child { // 子盒子样式
    float: left;
    height: 200px;
    width: 200px;
    background-color: green;
  }
    </style>
    
    <div class="parent"> 
    <div class="child"></div>
  </div>
image.png 可以看到虽然父盒子将子盒子包裹起来了,但是由于子盒子浮动脱离文档流,父盒子高度为0,所以不显示。 但当我们给父盒子开启一个BFC
    overflow: hidden;

image.png

父盒子的将计算子盒子的占位。

3. BFC 可以阻止元素被浮动元素覆盖

    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .div{
            width: 100px;
            height: 100px;
            background-color: red;
        }
        .div1{
            float: left;
        }
        .div2{
            margin: 20px;
            background-color: blue;
        }
    </style>
</head>
<body>
    <div class="div1 div"></div>
    <div class="div div2"></div>
</body>
</html>

image.png 可以看到由于浮动元素脱离文档流,会让两个元素重叠一起,但是当我们给div2开启了BFC之后,div2盒子就会避开div1

.div2{
    overflow: hidden;
 }

image.png

哪些情况会创建一个BFC?

1.浮动元素

float: left | right当元素设置为浮动后,它将脱离普通文档流,并创建一个 BFC。

2.绝对定位或固定定位元素

position: absolute | fixed这类元素也会自动创建一个 BFC。

3.特定的 display 值

  • (1) display: inline-block
  • (2) display: table-cell
  • (3) display: table-caption
  • (4) display: flex
  • (5) display: grid
  • (6) display: flow-root (专门用于创建块级格式化上下文)

以上这些 display 属性都会让该元素创建 BFC。

4.overflow 的值

overflow: hidden | auto | scroll只要设置了以上三个值之一,就会触发 BFC。

grid不仅会创建BFC,还会创建GFC

  • 外部显示类型为 BFC

  • 内部显示类型为 GFC (Grid Formatting Context)

类似的:

  • display: flex 也会创建:

  • 外部的 BFC

  • 内部的 FFC (Flex Formatting Context)

让我用代码演示:

<style>
    .grid-container {
        display: grid;
        grid-template-columns: 100px 100px;
        background: #eee;
        /* 这个容器对外是 BFC */
        /* 对内是 GFC,控制网格项目的排列 */
    }
    .float-element {
        float: left;
        width: 50px;
        height: 50px;
        background: red;
    }
</style>

<div class="float-element"></div>
<div class="grid-container">
    <div>1</div>
    <div>2</div>
    <!-- 因为外部是 BFC,所以不会与浮动元素重叠 -->
    <!-- 因为内部是 GFC,所以子元素按网格规则排列 -->
</div>

简单来说:同时拥有BFC和GFC的特性

这就是为什么 Grid 容器既能阻止外部浮动元素的干扰(BFC特性),又能让内部元素按网格方式排列(GFC特性)。