Block formatting context & Inline formatting context(BFC&IFC)的区别(转载)

何为BFC与IFC

bfc与ifc是针对页面正常流的两种环境,块级元素处于bfc环境中,行内元素处于ifc环境中。

元素是块级元素or行内元素由其display属性决定:

  • block, table, flex, grid, list-item 为块级
  • inline, inline-block, inline-table, inline-flex, inline-grid 为行内级

bfc与nfc就是块级元素与行内元素和外界的’隔离区域’

值得注意的是行内元素是不能直接放进bfc中的,每个bfc中的行内元素都会在其外部生成匿名块级元素来产生ifc环境

BFC与IFC的特性

先说bfc,在bfc中,元素排列特性为:

  • 元素纵向排列,由顶向下
  • 元素垂直间距取决于垂直方向margin,同一个bfc下的元素垂直方向margin会产生重叠
  • bfc内元素会与产生bfc的元素左对齐,即使存在浮动,如果从左往右的格式化则相反(因而会产生与浮动元素层叠问题)

而对于产生bfc的元素,又有以下特性:

  • bfc不会与float box叠加
  • 计算bfc高度时,其子元素中的float元素也参与计算
  • bfc是隔离区,其子元素不会对外界产生影响

再谈ifc,再ifc中的元素有以下特性:

  • 元素水平排布,横向的padding,margin,borders好使
  • ifc内元素垂直方向有多种对对齐方式,元素高度小于ifc高度时使用 ‘vertical-align’ 来决定垂直对齐方式,一行对齐完成后的方框叫做line box
  • 当多个行内元素横向排列超过line box宽度时(即一行放不下),他们会折行,形成多个line box,line box垂直并排不可分离或重叠,像p多行就是分离的。
  • 当同行内元素宽度和小于line box的宽度,横向对齐方式由text-align决定

而产生ifc的元素则有以下特性(其实ifc被分割为多个line box来看待,而整个ifc对外通常表现为bfc中的一个元素):

  • ifc的line box高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)
  • ifc中的line box一般左右都贴紧整个ifc,但是会因为float元素而扰乱。float元素会位于ifc与与line box之间,使得line box宽度缩短
  • 同个ifc下的多个line box高度会不同
  • ifc中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个ifc,每个ifc对外表现为块级元素,与div垂直排列。

bfc与ifc的产生条件

bfc产生条件比较复杂,通常元素位于一个大的bfc环境下,要产生独立的bfc需要以下条件:

  • 元素float为none以外的值
  • overflow除了visible 以外的值(hidden,auto,scroll )
  • display为table-cell,table-caption,inline-block, flex, inline-flex
  • position为absolute,fixed
  • fieldset元素

ifc的产生则是在行内元素出现情况则会出现,通常为行内元素外的匿名块

bfc与ifc的运用场景

bfc的运用比较普遍了,主要有以下几种:

  • 消除浮动:浮动元素参与bfc的高度计算,所以将元素设置为独立bfc可以防止元素塌陷
  • 两行布局:bfc不会与float box叠加,所以可以用于两行布局
  • 解决margin叠加:竖直方向的独立bfc不会出现margin叠加,相反同个bfc下的元素则会产生margin叠加

ifc的运用主要再水平与垂直对齐上

  • 水平居中:当一个块要在位置环境下水平对齐时,设置其为inline-block则会在外层产生ifc,通过text-align则可以使其水平居中,这个可以好理解
  • 垂直居中:  创建一个ifc,用一个元素撑开垂直距离,其他行内元素则可以在此距离下通过设置vertical-align垂直居中,撑开元素可以用:after定义一个高度为容器100%的inline-block,来把该行line box‘撑开’
<div id='ifc1'>
    <div id='middle-block'>形成了一个bfc,外界与其隔绝,同时此div又处于ifc环境</div>
</div>
<style>

#ifc1 {background-color:#f2f2f2; height:200px; text-align:center;}
#middle-block { vertical-align:middle; display:inline-block;}
#ifc1:after{content:'';height:100%;0;display:inline-block;margin-left:-5px;font-size:0;vertical-align:middle;}
</style>

一个特殊的display属性: inline-block

根据bfc的定义,display为inline-block的元素是会产生bfc的,但值得注意的是,inline-block的元素又具有行内元素的特质,那它所在的环境是否参与ifc呢,让我们进行以下简单的测试:

  • 将inline-block放入一个标准的ifc环境中:可以看出inline-block的元素遵循ifc的从左到右排布的原则
<div id='ifc'>this is another inline element
    <span id='element1'>this is in ifc</span>
    <div id='inline-block'>inline-block</div>
    <a id='element3'>ifc-end</a>
</div>
<style>
#ifc { background-color:#f2f2f2;margin-top:50px;}
#inline-block{display:inline-block;background:#FF495F;}
</style>
  • 然而奇怪的是inline-block并不遵循ifc的高度由元素真是高度决定的原则:span并没有撑开形成ifc环境块的高度,而inline-block则撑开了,当浏览器缩放到文字超过2行时,会发现inline-block撑开的其实是line box
<div id='ifc'>
 this is another inline element,if you turn window short u will find inline-block resize the line box
    <span id='element1'>this is in ifc</span>
    <div id='inline-block'>inline-block</div>
    <a id='element3'>ifc-end</a>
</div>
<style>
#ifc { background-color:#f2f2f2;margin-top:50px;}
#inline-block{display:inline-block;padding-top:20px;background:#FF495F;color:white;}
#element1{padding-top:40px;background:#4679BD;color:white;}
</style>

另外一个与inline-block相近的属性为inline-flex,都是以行内元素的方式排布但会撑开ifc。

原文地址:https://www.cnblogs.com/dingyufenglian/p/4846596.html