和面试官谈谈BFC

什么是BFC 首先,什么是FC,FC的全称是 Formating Context(格式化上下文)。元素在标准流里面都是一个FC,例如 div,p 标签等都是属于一个FC。
看一下W3c的文档对标准流和formatting context的解释 9.4 Normal flow
Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level boxes participate in a block formatting context. Inline-level boxes participate in an inline formatting context.
简而言之

  • 块级元素的布局是属于BFC(Block Formatting Context)
  • 行内级元素的布局是属于IFC(Inline Formatting Context)
那么我们可以理解为,块级元素布局的上下文环境就是BFC,它就是一个大箱子,与外部环境隔离
形成BFC条件(直接照搬MDN) 创建新的块格式上下文 元素不是唯一能够创建块格式上下文的元素。任何块级元素都可以通过应用某些 CSS 属性来创建一个 BFC
除了文档的根元素 () 之外,还将在以下情况下创建一个新的 BFC:
  • 使用float 使其浮动的元素
  • 绝对定位的元素 (包含 position: fixedposition: sticky
  • 使用以下属性的元素 display: inline-block
  • 表格单元格或使用 display: table-cell, 包括使用 display: table-* 属性的所有表格单元格
  • 表格标题或使用 display: table-caption 的元素
  • 块级元素的 overflow 属性不为 visible
  • 元素属性为 display: flow-rootdisplay: flow-root list-item
  • 元素属性为 contain: layout, content, 或 strict
  • flex items
  • 网格布局元素
  • multicol containers
  • 元素属性 column-span 设置为 all
总结一下:html是一个BFC, 但是body不是一个BFC,overflow属性除了visible外都是一个BFC
BFC的作用 9.4.1 [Block formatting contexts]() 【和面试官谈谈BFC】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).
简单概述如下
  • 在BFC中,box会在垂直方向上一个挨着一个排布
    难怪块级元素会独占一行,原来是BFC的作用

  • 垂直方向上的间距由margin属性决定
  • 在同一个BFC中,相邻两个box之间的margin会折叠
  • 在BFC中,每一个元素的左边缘是紧挨着包含块的左边缘的
    刚刚我们说html也是一个BFC,现在大家知道页面布局的时候为什么都会默认靠左对齐了吧

那这个东西有什么用呢
  • 解决margin折叠问题
    我们可以形成两个不同的BFC,因为只有在同一个BFC中,相邻两个box之间的margin会折叠

  • 解决浮动高度塌陷问题
    BFC解决高度塌陷需要满足两个条件 1.浮动的父元素触发BFC,形成独立的块格式化上下文 2.浮动元素的父元素是auto的

    10.6.7 ['Auto' heights for block formatting context roots]()
In certain cases (see, e.g., sections 10.6.4 and 10.6.6 above), the height of an element that establishes a block formatting context is computed as follows:
If it only has inline-level children, the height is the distance between the top of the topmost line box and the bottom of the bottommost line box.
If it has block-level children, the height is the distance between the top margin-edge of the topmost block-level child box and the bottom margin-edge of the bottommost block-level child box.
Absolutely positioned children are ignored, and relatively positioned boxes are considered without their offset. Note that the child box may be an anonymous block box.
In addition, if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges. Only floats that participate in this block formatting context are taken into account, e.g., floats inside absolutely positioned descendants or other floats are not.
BFC的高度是auto的情况下,是如下方法计算高度的
1.如果只有inline-level,是行高的顶部和底部的距离
2.如果有block-level,是由最底层的块上边缘和最底层块的下边缘之间的距离
3.如果有绝对定位元素,将被忽略
4.如果有浮动的元素,那么会增加高度以包括这些浮动元素的下边缘
网上也有很多BFC的例子,我就不写拉,有人看再补充点小例子

    推荐阅读