站点工具

用户工具


谈一谈你对BFC/IFC的理解

总结

BFC的全称是 Block formatting contexts (块级格式化上下文)。block:块级元素, formatting:格式化、规定...的格式, contexts:上下文、环境。翻译过来就是:BFC是规定内部块级元素格式(摆放规则)的一个独立的环境。BFC其实包含三层要素。

摆放规则约束的对象是内部的所有块级元素

这个规则是:一个块级元素占据一整行空间,一个挨一个从上到下排列,盒子间的垂直距离由margin决定。相邻块级盒子的垂直margin会出现折叠。BFC里的盒子左侧边缘不会超出BFC,除非这个盒子自己也变成了一个新的BFC。

“上下文”一般理解为:1. 一个由容器和子项参与构建的、遵循一定规则的、独立的环境;2. 同一上下文中的子项关系是平等的,能相互影响的,即使存在子项嵌套子项的情况;3. 子项可能创建新的上下文,对其潜逃的子项生效,与外层上下文有同样的规则,且新上下文中的子项与外层上下文的子项完全隔离。

html 根节点默认会创建一个BFC,在这个环境下的块级元素会遵循上述规则摆放。

给元素添加浮动、绝对定位、display: inline-block、overflow不为visible、display: flow-root 这些样式时会让元素创建新的BFC。

创建BFC就像给元素加了一层隔离带一样。对内,内部的块级元素仍然准守一样的摆放规则但无法超出自己所属的BFC容器。对外,这个创建了BFC的元素包括其所有的子元素被当成一个唯一独立的个体对待。

基于BFC这种“隔离带”的特性,一般用来做两件事:

  • 用来实现清除浮动。比如元素内有浮动子元素导致高度塌陷,给这个元素添加overflow: hidden 可以实现包裹浮动子元素。(因为创建了BFC,不允许孩子超出自己的边界)
  • 阻止父子元素外边距折叠。父子块级元素如果没设置边框和padding,外边距会产生折叠。给父元素添加 overflow: hidden后会阻止父子元素外边距折叠。

理解BFC的这种特性也能让我们简化CSS的写法,比如一个浮动元素或者绝对定位元素作为容器内包含一些浮动子元素,容器不需要额外设置clearfix来清除浮动的。因为自身拥有的浮动或者绝对定位属性已经默认创建了BFC,能隔离并包裹内部的浮动子元素。

IFC是内联格式化上下文(Inline formatting contexts)的缩写,同理,是规定内部内联元素摆放规则的一个独立的环境。

解析

阻止父子外边距折叠

<div class="box">
  <div class="child"></div>
</div>
<div class="box">2</div>
<style>
.box {
  width: 200px;
  height: 100px;
  margin: 10px;
  background: red;
  overflow: auto; /*阻止外边距折叠*/
}
.child {
  width: 100px;
  height: 50px;
  background: blue;
  margin: 20px;
}  
</style>

https://codepen.io/jirengu/pen/RwGWVaG

代码中.box使用overflow: auto创建属于自己的BFC,相当于创 建一个和外界绝缘的新独立空间,此时阻止了自己的外边距 与 .child的外边距的折叠。

  1. 清除浮动
<div class="container">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>
<style>
.container {
  border: 1px solid;
  overflow: auto;
  /*  overflow: hidden; */
  /*  display: inline-block; */
  /* float: left; */
  /* position: absolute;  */
  /* display: table-cell; */
}
.box {
  float: left;
  width: 100px;
  height: 100px;
  margin: 10px;
  background: red;
}
</style>

https://codepen.io/jirengu/pen/ZEpbKWV

给.container创建BFC,使其作为绝缘体隔绝内部浮动元素对其 他元素的影响,同时能撑开.container。注意:创建BFC需要添加额外的属性,而这些属性有各自特殊作用, 往往会带来一定副作用。display: flow-root虽然无副作用,但兼容 性很差( Can I use... Support tables for HTML5, CSS3, etc )。因此多数 情况下清除浮动使用伪元素clearfix的方式。

  1. 找bug

以下代码对应的效果图中出现一大片空白区域,产生空 白的原因是什么?如何修复?

在线简历找bug 地址

intro上为了清除浮动加了.clearfix,里面的::after设置 clear: both 意思是必须要到之前左浮元素的下面。而DOM 结构的前面的aside是左浮元素,所以::after跑到了aside的 下方,导致.intro高度过大出现大面积空白。

解决方法

给.intro创建BFC(如加上display: flow-root),隔绝.intro::after对aside的影响。

若愚 · 2023/02/09 14:34 · 谈一谈你对bfc_ifc的理解_前端剑指offer.txt