《面试系列》之什么是BFC?

面试时常常会被问到有关BFC的问题,虽然网上有关讲解BFC的文章很多,基本大篇理论知识,虽收获不少,但面对面试时,却不知如何回答,不能条理清晰、简单明了的回答出面试官想考察的内容,容易导致回答着把自己都给弄晕了(尤其在紧张的情绪下,非常容易导致越说越“乱”,从而造成面试官觉得你理解不到位的认知😭)。所以特此记录下来,一为了加深对BFC的理解,二则为了面试能更好的回答。

相关面试题

  1. 简述你对BFC规范的理解
  2. 对BFC规范(块级格式化上下文:block formatting context)的理解
  3. 如何创建块级格式化上下文(block formatting context),BFC有什么用
  4. 对BFC规范的理解?
  5. 等等

虽然上面题目看起来好像不太一样,但是其实最终考察的点都是一样的,咱们只需分为什么是BFCBFC有什么作用如何创建BFC子问题来依依回答即可。

什么是BFC? (What)

逢管面试怎么问BFC,咱们就先给它回答一波什么是BFC

BFC称为块级格式化上下文,是CSS中的一种渲染机制。是一个拥有独立渲染区域的盒子(也可以理解为结界),规定了内部元素如何布局,并且盒子内部元素与外部元素互不影响。

对应的还有IFC、GFC和FFC(后两个CSS3引入)

BFC有什么作用? (Why)

上面我们知道BFC规定了内部元素的布局渲染,让我们查看下CSS规范文档,看下BFC有哪些规则:

文档规则

  1. 在一个块格式化上下文中,盒在垂直方向一个接一个地放置,从包含块的顶部开始。
  2. 两个兄弟盒之间的垂直距离由margin属性决定。
  3. 同一个块格式化上下文中的相邻块级盒之间的垂直外边距会合并。
  4. 同一个块格式化上下文中,每个盒的左外边界(left outer edge)挨着包含块的左外边界(对于从右向左的格式化,右外边界挨着)。
  5. BFC的区域不会与float box重叠。
  6. 计算BFC的高度时,浮动元素也参与计算。

详细规则可以查看9.4.1 块格式化上下文

规则图解

规则1和规则2应该是好理解的,这里就不展开叙述,如果你不明白,那么你可能学了个假CSS。😂

同一个块格式化上下文中的相邻块级盒之间的垂直外边距会合并

这里是讲margin collapse, 其实是有如下情况会发生合并: 1. 父子外边距;2. 兄弟外边距;3. 没有高度的元素自身margin-topmargin-bottom会合并。

不过有几点需要注意:

  1. 需要属于普通流中的盒子: 也就是脱离文档流不算
  2. 毗邻: 也就是元素间没有被paddingborderclearline box分隔开
  3. 垂直: 也就是margin-topmargin-bottom

只有满足上面几点才会发生margin合并效果。

父子合并

上图可以看到,父子的margin-topmargin-bottom发生了合并。如何解决呢?触发元素的BFC即可(注:下面都以设置元素overflow:hidden来触发),不过这里问题来了,我们是触发父元素的BFC还是子元素的BFC呢?

经过试验,我发现只有触发父元素的BFC才能避免margin合并,触发子元素的BFC并无效果。

这里父元素生效可以借用标准来解释:

Margins of elements that establish new block formatting contexts (such as floats and elements with “overflow” other than “visible”) do not collapse with their in-flow children.(创建了BFC的元素不会和它的子元素发生外边距叠加)

那触发子元素为何没有生效呢?这里我们先看下兄弟之间的合并。

兄弟合并

同样发生了margin合并,这里不存在父子关系,所以我们随便触发某个元素的BFC来看看效果。

触发child1BFC

发现还是发生margin合并,按照规则,虽然触发了child1的BFC,但是两个元素还是处于同一个BFC。

经过以上试验,我得出了未完全经官方认知的结论:

BFC影响的是内部元素

  1. 比如父子中,设置child为BFC,因为影响的是内部,所以child还是和par处于同一个BFC中
  2. 兄弟中,设置child1为BFC,影响的是child1的子元素,但child1和child2还是处于同一个BFC

所以我可以使用一个div进行包裹,并触发该div的BFC,从而使得处于不同的BFC中,来避免margin合并。

父子合并触发子元素BFC

兄弟元素触发BFC

完美!🎉,我们这样就可以通过触发BFC来避免margin合并了,当然避免margin合并还有很多方法,比如设置border等等。

BFC的区域不会与float box重叠

当我们设置一个元素为float,该元素脱离文档流,会覆盖在下方元素上面。

float重叠

而如果设置元素BFC,将不会与float重叠,这样我们可以通过该属性来实现自适应两栏布局。

BFC解决float重叠

计算BFC的高度时,浮动元素也参与计算

因为浮动元素会脱离文档流,所以包含块元素的高度不会包含该浮动元素,导致高度发生塌陷。使用BFC,包含块的高度包含浮动元素在内。

不触发BFC

触发BFC

根据规则+实例,给出BFC有什么作用。

如何创建BFC?(How)

  1. 根元素,即html
  2. float的值不为none
  3. overflow的值不为visible
  4. display的值为inline-blocktable-celltable-caption
  5. position的值为absolutefixed
  6. 等等

如有不对之处,还恳请指出,谢谢~ 🖖

好累,花了将近4个小时,第一遍没保存,又重新写了一遍。😭

推荐文章