关于 BFC

BFC(Block formattingcontext)直译为”块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干.(简单点说,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用)

W3C的定义`

浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。

BFC是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子里面物品的摆放是不受外界的影响的。转换为BFC的理解则是:BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。

BFC布局规则

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

产生BFC的元素

  1. 根元素
  2. float属性不为none
  3. overflow不为visible
  4. display为inline-block, table-cell, table-caption, flex, inline-flex,position为absolute或fixed
  5. position为absolute或fixed

BFC作用

  1. 自适应两栏布局

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
      <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布局规则第3条:

每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此

因此,虽然存在浮动的元素aslide,但main的左边依然会与包含块的左边相接触。
 根据BFC布局规则第四条:

BFC的区域不会与float box重叠。

我们可以通过通过触发main生成BFC, 来实现自适应两栏布局。

1
2
3
.main {
overflow: hidden;
}

当触发main生成BFC后,这个新的BFC不会与浮动的aside重叠。因此会根据包含块的宽度,和aside的宽度,自动变窄。效果如下:
此处输入图片的描述

  1. 防止垂直 margin 重叠
    more

BFC包含浮动

浮动元素是会脱离文档流的(绝对定位元素会脱离文档流)。如果一个没有高度或者heightauto的容器的子元素是浮动元素,则该容器的高度是不会被撑开的。我们通常会利用伪元素(:after或者:before)来解决这个问题。BFC能包含浮动,也能解决容器高度不会被撑开的问题。
此处输入图片的描述

1
2
3
4
5
6
7
8
9
10
11
12
<div class="container">
<div>Sibling</div>
<div>Sibling</div>
</div>
.container {
background-color: green;
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}

在上面这个例子中,容器没有任何高度,并且它包不住浮动子元素,容器的高度并不会被撑开。为解决这个问题,可以在容器中创建一个BFC:

1
2
3
4
5
6
7
8
9
  .container {
overflow: hidden; /* creates block formatting context */
background-color: green;
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}

现在容器可以包住浮动子元素,并且其高度会扩展至包住其子元素,在这个新的BFC中浮动元素又回归到页面的常规流之中了。


使用BFC避免文字环绕
此处输入图片的描述
如上图所示,对于浮动元素,可能会造成文字环绕的情况(Figure1),但这并不是我们想要的布局(Figure2才是想要的)。要解决这个问题,我们可以用外边距,但也可以用BFC。


在多列布局中使用BFC
如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。


参考文章:
http://www.ido321.com/1642.html
http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
http://www.html-js.com/article/1866