Skip to content

简介

BFC指的是Block Formatting Context, 也就是 块级格式化上下文,是用于布局块级盒的一块 渲染区域。

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

简单来说就是,BFC是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局。那么怎么使用BFC呢,BFC可以看做是一个CSS元素属性。

1. 触发条件

  • 根元素,即 HTML 元素
  • float浮动元素:float 值为 left、right
  • overflow 值不为 visible,为 auto、scroll、hidden
  • display 的值为 inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
  • position 的值为 absolute 或 fixed(不是static或者relative)

2. 渲染规则

  • 内部的Box会在垂直方向,从顶部开始一个接一个地放置。
  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生叠加,与方向无关。
  • 每个元素的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC 的区域不会与 float 的元素区域重叠。
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
  • 计算BFC的高度时,浮动元素也参与计算。

BFC目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素。

3. 解决了什么问题

当一个容器具备了 BFC 之后, 我们就可以利用BFC的特性,解决很多问题

防止 margin 重叠(塌陷)

<style>
    .box {
      width: 100px;
      height: 100px;
      background: red;
      margin: 20px;
    }
</style>
<body>
    <div class="box">1</div>
    <div class="box">2</div>
</body>

按样式代码来看,两个div之间间距应该是40px。但实际上是20px。这就是BFC渲染规则的第二点(margin重叠)。

可以在p外面包裹一层容器,并触发这个容器生成一个BFC,那么两个p就不属于同一个BFC,则不会出现margin重叠。

<style>
    .box {
      width: 100px;
      height: 100px;
      background: red;
      margin: 20px;
    }
    .bfc {
      overflow: hidden;
    }
</style>
<body>
    <div class="box">1</div>
    <div class="bfc">
      <div class="box">2</div>
    </div>
</body>

清楚浮动解决高度坍塌

<style>
  	.par {
     	 border: 5px solid #fcc;
    	  background: #000;
    	  width: 300px;
    }

    .child {
    	  border: 5px solid #f66;
    	  width: 100px;
    	  height: 100px;
    	  float: left;
    }
</style>
<body>
    <div class="par">
      <div class="child"></div>
      <div class="child"></div>
    </div>
</body>

给子box设置完float结果脱离文档流,使父高度没有被撑开,高度坍塌,从而背景颜色没有颜色出来,解决此问题可以给利用上面触发BFC的任意一种方式方法触发父box的BFC。

例如给父元素加display: inline-block属性。

 .par {
      border: 5px solid #fcc;
      background: #000;
      width: 300px;
      display: inline-block;
    }

自适应多栏布局

这里举个两栏的布局。

<style>
    body {
      width: 300px;
      position: relative;
    }

    .aside {
      width: 100px;
      height: 150px;
      float: left;
      background: #f66;
    }

    .main {
      height: 200px;
      background: #fcc;
    }
  </style>
  <body>
    <div class="aside"></div>
    <div class="main"></div>
  </body>

BFC规则每个元素的左外边距与包含块的左边界相接触。因此,虽然.aslide为浮动元素,但是main的左边依然会与包含块的左边相接触

而BFC的区域不会与浮动盒子重叠,所以我们可以通过触发main生成BFC,以此适应两栏布局。

.main {
      height: 200px;
      background: #fcc;
      overflow: hidden;
  }

这时候,新的BFC不会与浮动的.aside元素重叠。因此会根据包含块的宽度,和.aside的宽度,自动变窄。

4. 结论

可以看到上面几个案例,都体现了BFC实际就是页面一个独立的容器,里面的子元素不影响外面的元素。

扩展参考

从清除浮动引起的BFC,IFC,FFC再学习 | DLLCNX BLOG请说说什么是BFC?大白话讲清楚