BFC 详解

BFC深入解析

如何定义BFC的含义

BFC(block formatting context)就是“块级格式化上下文”的意思,创建了 BFC的元素就是一个独立的盒子,不过只有Block-level box可以参与创建BFC, 它规定了内部的Block-level Box如何布局,并且与这个独立盒子里的布局不受外部影响,当然它也不会影响到外面的元素。

Block-level Box:display属性为block, list-item, table的元素

w3c规范中的BFC定义:

  1. 在BFC中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。
  2. 浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。
  3. 在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。
  4. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
  5. 计算BFC的高度时,浮动元素也参与计算。

通俗定义:

BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)并且在一个BFC中,块元素与行元素,都会垂直的沿着其父元素的边框排列。

如何触发BFC

  1. float 除了none以外的值
  2. overflow 除了visible 以外的值(hidden,auto,scroll )
  3. display (table-cell,table-caption,inline-block, flex, inline-flex)
  4. position值为(absolute,fixed)
  5. fieldset 元素 或是设置display使其具有它的特性(flex,grid,table…等)

运用

BFC运用场景主要集中在float、绝对定位、margin collaspe中。

清楚浮动带来的影响就是这个原理

  • 上述中触发BFC来消除浮动的影响
  • clear: both; 使其产生 clearance 它带一些间隙使

案例
此处本应该受到 box 浮动影响的 p 添加 overflow: hidden; 使其产生新的BFC,使其不受外界浮动元素的影响。

外边距折叠 与 BFC

在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的上下外边距可能会重叠。这种上下外边距会重叠的方式被称为折叠,并且重叠的外边距我们称之为折叠外边距。

折叠的结果

  • 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
  • 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
  • 两个外边距一正一负时,折叠结果是两者的相加的和。

折叠的条件

  • 必须是处于常规文档流(非float和绝对定位)的块级元素,并且处于同一个BFC当中。
  • 没有行内元素,没有空隙(clearance),没有padding和border将他们分隔开
  • 都属于垂直方向上相邻的外边距,可以是下面任意一种情况
  • 元素的margin-top与其第一个常规文档流的子元素的margin-top
  • 元素的margin-bottom与其下一个常规文档流的兄弟元素的margin-top
  • height为auto的元素的margin-bottom与其最后一个常规文档流的子元素的margin-bottom
  • 高度为0并且最小高度也为0,不包含常规文档流的子元素,并且自身没有建立新的BFC的元素的margin-top和margin-bottom

小结

  • 创建了新的BFC的元素(例如浮动元素或者’overflow’值为’visible’以外的元素)与它的子元素的外边距不会折叠
  • 浮动元素不与任何元素的外边距产生折叠(包括其父元素和子元素)
  • 绝对定位元素不与任何元素的外边距产生折叠
  • inline-block元素不与任何元素的外边距产生折叠
  • 一个常规文档流元素的margin-bottom与它下一个常规文档流的兄弟元素的margin-top会产生折叠,除非它们之间存在间隙(clearance)。
  • 一个常规文档流元素的margin-top 与其第一个常规文档流的子元素的margin-top产生折叠,条件为父元素不包含 padding 和 border ,子元素不包含 clearance。
  • 一个 ‘height’ 为 ‘auto’ 并且 ‘min-height’ 为 ‘0’的常规文档流元素的 margin-bottom 会与其最后一个常规文档流子元素的 margin-bottom 折叠,条件为父元素不包含 padding 和 border ,子元素的 margin-bottom 不与包含 clearance 的 margin-top 折叠。
  • 一个不包含border-top、border-bottom、padding-top、padding-bottom的常规文档流元素,并且其 ‘height’ 为 0 或 ‘auto’, ‘min-height’ 为 ‘0’,其里面也不包含行盒(line box),其自身的 margin-top 和 margin-bottom 会折叠。

总结

BFC是页面元素里一个独立存在作用块,它不影响它外面的布局,外面的元素也不会影响到BFC里面的布局。

参考文章: