CSS中的BFC

一、BFC是什么?

它是 Block Formatting Context (块级格式化上下文) 的简称,接下来通过对其中几个名词的解释进一步了解 BFC 定义。

  1. Box : CSS布局的基本单位
      Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。
  • 几个常见的盒子:
    block-level boxdisplay 属性为 block,list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context;
    inline-level boxdisplay 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;
  1. Formatting context
      Formatting context 是指页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称 BFC )和 Inline formatting context (简称 IFC )。

  2. **BFC **:块级格式化上下文
      BFC 是指一个独立的块级渲染区域,只有Block-level Box参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。

    • BFC就是一种布局方式,可以理解为一个作用范围,即在一个BFC里的布局与其之外的布局不相关或者说不相互影响。
  • 举一个形象的例子:
    可以把一个页面想象成大的集装箱,这个集装箱里装的货物就是 html元素。在现实生活中为了避免不同人的货物相互混淆,都是把货物打好包装再装入集装箱,这样的话无论你包装里面的货物怎么摆放,都不会影响到其他人的货物。那么这个包装就可以被想象成 Block Formatting Context。

4. 为什么要用BFC?

  • 使用一定的CSS声明可以生成BFC,浏览器对生成的BFC有一系列的渲染规则,利用这些渲染规则我们可以达到一定的布局效果,为了达到特定的布局效果我们让元素生成BFC。

二、哪些元素会生成BFC?

  • 当一个HTML元素满足下面条件的任何一点,都可以产生 Block Formatting Context

  • 根元素

  • float的值不为none

  • overflow的值不为visible(可以为hidden,scroll,auto);

  • display的值为inline-block,table-cell,table-caption,flex,inline-flex中的任何一个;

  • position的值为absolute,fixed(不为static,relative中的任何一个);

  • displaytable也认为可以生成BFC,其实这里的主要原因在于table会默认生成一个匿名的table-cell,正是这个匿名的table-cell生成了BFC。

  • 常用的用来触发BFC的CSS样式:
    overflow: scroll,overflow: hidden,display: flex, float: left,display: table

  • 其中可能产生的一些问题

  • display:table —— 可能会产生一些问题

  • overflow:scroll —— 可能会显示不必要的滚动条

  • overflow:hidden —— 将会剪切掉溢出的元素

  • float:left —— 将会把元素置于容器的左边,其他元素环绕着它

三、BFC的布局规则

  1. 内部的Box会在垂直方向上一个接一个的放置;
  2. 垂直方向上的距离有margin决定。(完整的说法是:属于同一个BFC的两个相邻的Box的margin会发生重叠,与方向无关)
  3. 每个盒子的左外边框紧挨着包含块的左边框(从右到左的格式,则为紧挨右边框),即使浮动元素也是如此。(这说明BFC中的子元素不会超出它的包含块)
  4. BFC的区域不会与float的元素区域重叠
  5. 计算BFC的高度时,浮动子元素也参与计算;
  6. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;

四、BFC的作用及原理

  • 自适应两栏布局
 body { width: 300px; } 
.aside { width: 100px; height: 150px; float: left; background: #f66; } 
.main { height: 200px; background: #fcc; }
<body> 
     <div class="aside"></div> 
     <div class="main"></div>
</body>
  • 效果图如下:


  • 分析:

根据BFC布局规则 第3条:
* 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此。

现象:虽然存在浮动的元素 aside,但 main 的左边依然会与包含块的左边相接触。

  • 修改:
根据BFC布局规则第四条:
* BFC的区域不会与float box重叠。

改变方法:我们可以通过触发 main 生成BFC, 来实现自适应两栏布局,当触发main 生成BFC后,这个新的BFC不会与浮动的 aside 重叠,main 会根据包含块的宽度,和 aside 的宽度,自动变窄。(一个盒子的边框会由于浮动而收缩,盒子本身将会变得更窄)

.main { overflow: hidden;}  //或者利用上述其他方式为它生成 BFC
  • 新的效果图如下:


  • 清除内部浮动
.par { border: 5px solid #fcc; width: 300px; }
.child { border: 5px solid #f66; width: 100px; height: 100px; float: left;}
<body> 
    <div class="par"> 
      <div class="child"></div> 
      <div class="child"></div>
    </div>
</body>
  • 效果图如下:


  • 修改:

根据BFC布局规则第五条:
* 计算BFC的高度时,浮动元素也参与计算
**改变方法:**为达到清除内部浮动,我们可以触发 par 生成BFC,那么 par 在计算高度时,par 内部的浮动元素 child 也会参与计算。
.par { overflow: hidden;} //或者利用上述其他方式为它生成 BFC
  • 新的效果图如下:


  • 防止垂直 margin 重叠
<style> 
  p { color: #f55;
       background: #fcc; 
       width: 200px;
       line-height: 100px;
       text-align: center; 
       margin: 100px;
     }
</style>
<body> 
    <p>Haha</p> 
    <p>Hehe</p>
</body>
  • 效果图如下:


  • 分析:

根据BFC布局规则第二条:

Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
现象:两个p之间的距离为100px,发送了margin重叠。

  • 修改:

我们可以在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了。

<style>
     .wrap { overflow: hidden; }
     p { 
          color: #f55; 
          background: #fcc;
          width: 200px; 
          line-height: 100px;
          text-align: center;
          margin: 100px; 
        }
</style>
<body>
     <p>Haha</p> 
     <div class="wrap">
       <p>Hehe</p>
     </div>
</body>
  • 新的效果图如下:


其实以上的几个例子都体现了BFC布局规则第六条:
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
    解释:
    因为BFC内部的元素和外部的元素绝对不会互相影响;
    因此,** 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠;
    同样的,
    当BFC内部有浮动时**,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度;避免margin重叠也是这样的一个道理。

五、详细分析 margin 折叠

  • 1、产生的原因

  • 这些margin都处于普通流中,并在同一个BFC中

  • 这些margin没有被非空内容、paddingborderclear 分隔开

  • 这些margin在垂直方向上是毗邻的

  • 2、包含的情况:

    • 一个box的 margin-top 与第一个子box的 margin-top
    • 一个box的 margin-bottom 与最后一个子box的 margin-bottom ,但须在该box的height:auto 的情况下
    • 一个box的 margin-bottom 与紧接着的下一个box的margin-top
    • 一个box的margin-top与其自身的margin-bottom,但须满足没创建BFC
      :另一篇CSS盒子对这些情况有图解
  • 3、折叠边距的计算

  • 当两个margin都是正值的时候,取两者的最大值;

  • 当 margin 都是负值的时候,取的是其中绝对值较大的,然后,从 0 位置,负向位移;

  • 当有正有负的时候,先取出负 margin 中绝对值中最大的,然后,和正 margin 值中最大的 margin 相加。
    NOTE:所有毗邻的margin要一起参与运算,不能分步进行。

  • 4、举个例子:

  • 1)用 浮动布局 显示成两行两列 ——(为了解决浮动布局里的一个问题:元素浮动不换行怎么办?)

<div id="A">
  <div id="red" style="background: red;width: 100px;height: 100px;float: left;">
  </div>
  <div id="orange" style="background: orange;width: 100px;height: 100px;float: left;">
  </div>
</div>
<div id="B">
  <div id="yellow" style="background: yellow;width: 100px;height: 100px;float: left;">
  </div>
  <div id="green" style="background: green;width: 100px;height: 100px;float: left;">
  </div>
</div>
效果图
效果图
我们可以看到四个盒子最终都处在一列里面,为了达到我们的目的,可以**在其中一个外层盒子建立一个BFC**
<div id="A" style="display:inline-block;">
...
</div>
<div id="B">
...
</div>
新的效果图
新的效果图
    1. 实现多栏布局的一种方式
根据BFC布局规则第四条:
* BFC的区域不会与float box重叠。(与浮动元素相邻的已生成BFC的元素不能与浮动元素互相覆盖)

利用该特性可以作为多栏布局的一种实现方式。

```

<div class="container">
<div class="column">column 1</div>
<div class="column">column 2</div>
<div class="column">column 3</div>
</div>

.column {
width: 31.33%;
background-color: green;
float: left;
margin: 0 1%;
}
.column:last-child
{
float: none;
overflow: hidden;
}


    ![多列布局.png](http://upload-images.jianshu.io/upload_images/3087126-a263255605a63fa0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###六、关于BFC的总结
* BFC的几个用途 (但是也有其他方法可以达到这种效果)
 * 1、BFC可以阻止垂直边距叠加问题
 * 2、BFC可以包含内部元素的浮动
 * 3、BFC可以阻止元素被浮动覆盖
 * 4、BFC可以决定清除浮动的范围

>参考文章:
[BFC(块级格式化上下文)](http://www.jianshu.com/p/66632298e355)
[我对BFC的理解](http://www.jianshu.com/p/76484dff1cb5)

>其他文章推荐:
[理解CSS中的BFC](http://www.w3cplus.com/css/understanding-block-formatting-contexts-in-css.html)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,504评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,898评论 1 300
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,218评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,322评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,693评论 3 290
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,812评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,747评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,476评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,700评论 2 251
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,190评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,541评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,206评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,129评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,903评论 0 199
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,894评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,748评论 2 274

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,630评论 1 92
  • BFC是什么? BFC(Block Formatting Context)直译为“块级格式化范围 ”。 是 W3C...
    若邪Y阅读 1,758评论 0 2
  • 开篇 一些元素,如float元素,如position为absolute,inline-block,table-ce...
    Pursue阅读 11,400评论 13 56
  • 一、什么是BFC Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一...
    浪里行舟阅读 645评论 0 3
  • 先前在学习CSS float时,有同学提到了BFC这个词,作为求知好问的好学生,哪里不懂查哪里,那么今天就来研究一...
    这名字真不对阅读 6,439评论 3 19