css

BFC 是什么东西

先来看看W3C对BFC的定义:

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other than ‘visible’ (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the ‘margin’ properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.

In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

这段描述里面提到的最多的两个词是box,block formatting contexts,毫无疑问,box就是我们常说的盒模型,block formatting contexts就是BFC,我们先来详细说说这两个东西

Box: CSS布局的基本单位

Box是CSS布局的对象和基本单位,整个页面都是由Box组成的。元素的类型和display属性决定了这个Box的类型,不同类型的Box会参与不同的Formatting Contents,因此Box内的元素会以不同的方式来渲染:

  • Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the ‘display’ property make an element block-level: ‘block’, ‘list-item’, and ‘table’. Block-level boxes are boxes that participate in a block formatting context.
  • Inline-level elements are those elements of the source document that do not form new blocks of content; the content is distributed in lines (e.g., emphasized pieces of text within a paragraph, inline images, etc.). The following values of the ‘display’ property make an element inline-level: ‘inline’, ‘inline-table’, and ‘inline-block’. Inline-level elements generate inline-level boxes, which are boxes that participate in an inline formatting context. An inline box is one that is both inline-level and whose contents participate in its containing inline formatting context.

Formatting Contexts:

Formatting Contexts是W3C CSS2.1规范里面的一个概念,他是页面中一个渲染区域,并且有一套渲染规则,他决定了其子元素将如何定位,以及和其他元素的关系和相互作用。比较常用的Formatting Contexts有BFC和IFC,FFC(我大爱的FFC后面在写文章来说吧)

BFC 布局规则

  • 内部的box一个接一个的排列下来,在垂直方向上
  • 垂直方向上的margin由相邻的两个Box的margin决定,会发生叠加效果
  • 每个元素的左边的包含块的左边接触
  • BFC区域不会和float box叠加
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然

如何触发BFC

下列情况将创建一个块格式化上下文:

  • 根元素或其它包含它的元素
  • 浮动 (元素 float 不为 none)
  • 绝对定位元素 (元素 position 为 absolute 或 fixed)
  • 内联块 inline-blocks (元素 display: inline-block)
  • 表格单元格 (元素 display: table-cell,表格单元格默认属性)
  • 表格标题 (元素 display: table-caption, 表格标题默认属性)
  • 被声明为块级的元素 overflow 不为 visible
  • 弹性盒 flex boxes (元素 display: flex 或 inline-flex)

BFC 应用

我们来实现一个两栏自适应布局,

<style>
.body {
    width: 300px;
    position: relative;
}
.aside {
    width: 100px;
    height: 150px;
    float: left;
    background: #f66;
}
.main {
    height: 200px;
    background: #fcc;
}
</style>
<div class="body">
    <div class="aside"></div>
    <div class="main"></div>
</div>

这个时候main会包围aside区域,这是由于float导致的。要想实现两栏布局,我们可以通过触发main生成BFC来实现。

.main {
    overflow: hidden;
}

参考资料

Block_formatting_context

http://www.w3.org/TR/CSS2/visuren.html#box-gen

http://www.w3.org/html/ig/zh/wiki/CSS2/visuren#block-formatting