用通俗的话解释BFC

437 阅读4分钟

前端程序员在布局页面时,经常会遇到各种烦人的小问题,比如:每个元素都是一个盒子,盒子外的父元素应该不会受到盒内子的子元素影响,可是事实是这样的吗?

往往,我们会看到子元素浮动后,父元素高度没有了,两栏布局时右侧没有自适应,垂直方向上上下两个元素外边距不太对

从常理上来说,被包含在父元素里的元素是不会影响到父元素旁边的元素,但实际上并不总是如此,那么有没有什么办法能让里面的元素和外部真正隔离开呢? ==> 解决办法就是:BFC

BFC:block formatting contexts

MDN 对 BFC 的描述

一个块格式化上下文(block formatting context) 是Web页面的可视化CSS渲染出的一部分。它是块级盒布局出现的区域,也是浮动层元素进行交互的区域。 一个块格式化上下文由以下之一创建: 根元素或其它包含它的元素

  • 浮动元素 (元素的 float 不是 none)
  • 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
  • 内联块 (元素具有 display: inline-block)
  • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
  • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
  • 具有overflow 且值不是 visible 的块元素,
  • display: flow-root
  • column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。

一个块格式化上下文包括创建它的元素内部所有内容,除了被包含于创建新的块级格式化上下文的后代元素内的元素。 块格式化上下文对于定位 (参见 float) 与清除浮动 (参见 clear) 很重要。定位和清除浮动的样式规则只适用于处于同一块格式化上下文内的元素。浮动不会影响其它块格式化上下文中元素的布局,并且清除浮动只能清除同一块格式化上下文中在它前面的元素的浮动。

MDN给的定义比较抽象

现在我们来总结一下,究竟什么是BFC呢?

BFC简称块级格式化上下文,是官方的边距重叠解决方案。简单来说,BFC就是页面的块区域,限定了浮动元素和其他元素的交互区域,可以解决边距重叠问题。 BFC是一个独立的布局环境,其中的元素布局是不受外界影响的,并且在一个BFC中,块盒和行盒(行盒由一行中所有的内联元素所组成),都会垂直的沿着其父元素的边框排列。

BFC的目的就是:形成一个完全独立的空间,让空间中的子元素不会影响到外面的布局。如何才能形成这样一个神奇的空间呢?我们通过CSS为元素设置一些属性,就能触发,常用的有四种:

1、float的值不是none; 2、position的值不是static或者relative; 3、display的值是inline-block、table-cell、flex、table-caption、flow-root或者inline-flex; 4、overflow的值不是visible。

下面按照定义一个一个试

1.浮动

<div class="parent">
    <div class="son"></div>
</div>
<style>
.parent {
  border:1px solid red;
  min-height: 10px; 
  float: left;
}
.son {
  height: 100px;
  background: green;
  float:left;
  width:400px;
} 
</style>

给父元素div float:left样式以后,可以包住里面的内容

2.绝对定位

<div class="parent">
    <div class="son"></div>
</div>
<style>
.parent{
  border:1px solid red;
  min-height: 10px; 
  float: left;
}
.son {
  height: 100px;
  background: green;
  position: absolute;
  width:400px;
} 
</style>

给父元素div position: absolute;样式以后,可以包住里面的内容

3.display不为block的block

<div class="parent">
    <div class="son"></div>
</div>
<style>
.parent {
  border:1px solid red;
  min-height: 10px; 
  float: left;
}
.son{
  height: 100px;
  background: green;
  display:inline-block;
  width:400px;
} 
</style>

给父元素div position: absolute;样式以后,可以包住里面的内容

4.overflow不为visible的块盒

<div class="parent">
    <div class="son"></div>
</div>
<style>
.parent {
  border:1px solid red;
  min-height: 10px; 
  overflow:hidden;
}
.son {
  height: 100px;
  background:green;
  width:400px;
} 
</style>

给父元素div overflow:hidden;样式以后,可以包住里面的内容

5.新属性display : flow-root

<div class="parent">
    <div class="son"></div>
</div>
<style>
.parent {
  border:1px solid red;
  min-height: 10px; 
  display : flow-root
}
.son{
  height: 100px;
  background:green;
  width:400px;
} 
​
</style>

此属性是css3新增属性是让当前元素触发BFC,专门用来包住子元素的,并且不会引发任何的bug。

上述方法都可以创建BFC,但是会带来一些负面影响:

1、display:table 可能会引发响应性问题; 2、overflow:scroll 可能产生多余的滚动条; 3、float:left 将把元素移至左侧,并被其他元素环绕; 4、overflow:hidden 将裁切溢出元素。

总结一下,触发BFC可以解决:

  1. 浮动元素的父元素高度塌陷
  2. 两栏自适应布局
  3. 外边距垂直方向重合

参考文献

1.developer.mozilla.org/zh-CN/docs/…