BFC的通俗理解:

  Block Formatting Context(块级格式化上下文)是W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。

  简单来讲,我们可以把它理解为,我们在进行盒模型布局的时候,如果一个元素符合了成为BFC的条件,该元素成为一个隔离了的独立容器,元素内部元素会垂直的沿着其父元素的边框排列,和外部元素互不影响 。比如浮动元素会触发BFC,浮动元素内部的子元素主要受到该浮动元素的影响,而两个浮动元素之间是互不影响的。

  在CSS3 中,BFC 叫做Flow Root。在早期的ie中也有类似的概念haslayout IE6、7的很多布局产生的bug(如3px间隙、绝对定位的继承宽度)都可以通过触发hasLayout修复,比较推荐的方法为zoom:1与height:1%,不会破坏已有的样式,相信大家对它并不陌生。

  同样的以往集中在float、绝对定位、margin collaspe中的很多困惑,在理解了bfc后,都能够被我们一一解除 。

BFC规范中的定义:

w3c规范对BFC的解释:
  浮动元素和绝对定位元素,不是块级盒子的块容器 (如 inline-blocks, table-cells, 和 table-captions),以及设置了overflow属性(除了visible)的块级盒子 ,都会为他们的内容创建新的BFC(块级格式上下文)。
  在BFC中,盒子从顶端开始垂直地 一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。
  在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。

触发BFC的方法:

float 元素
position(absolute,fixed)
display (table-cell,table-caption,inline-block)
overflow 除了visible 以外的值(hidden,auto,scroll )
fieldset元素
早期IE的hasLayout会触发一个新的block formatting context

BFC的特性

  1. 边缘不和浮动元素重叠
  2. 不存在collapsing margins问题

  第一个特性特别有用,因为元素触发了BFC的话,就不会被float元素覆盖,当子元素全部浮动的时候也能够正确地包含了
  第二个margin不会叠加的特性,可以理解为两个处于普通流的盒子,会有margin叠加的问题,是因为他们属于相同的BFC,当他自身创建了一个新的BFC时,这个问题就不存在了

BFC的常见应用

1.通过边缘不和浮动元素重叠的特性,实现两栏结构。

  如果一个浮动元素后面跟着一个非浮动的元素,那么就会产生一个覆盖的现象,通过触发BFC来清除覆盖,很多自适应的两栏布局就是这么做的。
下面我们来看左边图片+右边信息的示例:

// CSS
div,p{margin:;padding:;}
.box {width:320px;}
.img {width: 80px;height: 80px;margin-right:10px;float:left;}
.info {background: #ff9;color: #404040;} // HTML
<div class="box">
<div class="img"><img src="http://wwc.taobaocdn.com/avatar/getAvatar.do?userNick=feihu2987&width=80&height=80&type=sns" width="80" height="80" alt="头像"></div>
<p class="info">风吹亮雪花,吹白我们的头发,当初说一起闯天下,你们还记得吗?</p>
</div>

一般情况下它呈现出我们所乐意看到的样子:

但随着文字信息增多后,会变地非常的糟糕:

很明显,这是因为info类里面的文字受到了浮动元素的影响,但这并不是我们所期望的。此时我们可以为P元素的内容建立一个BFC,让其内容消除对外界浮动元素的影响。根据上文所知,只要给info元素添加overflow:hidden;即可为其内容建立新的BFC。当然你也可以通过其他方法来建立。其效果如下:

至此,我们可以抛弃计算设置左边边距,或是设置右边浮动再清除父元素的浮动这些弱爆的方式了。

demo地址: http://jsfiddle.net/k9u5x/

当然考虑到ie6 7 的兼容性,我们同时触发一下 haslayout就再好不过了,更多示例请看豆瓣小组和阅读中,很多地方使用了此方式:

http://www.douban.com/group/explore/culture

.channel-item .bd, .channel-item .block,.channel-item .block p, .mod .hd, .channel-group-rec li, .channel-group-rec li .info {
overflow: hidden;
zoom:;
}


2.清除元素内部浮动

只要把父元素设为BFC就可以清理子元素的浮动了,同样的因为IE6-7不支持BFC,因此要设置zoom:1来触发hasLayout 闭合浮动。

我们最常见的兼容用法就是在父元素上添加class clearfix ;

.clearfix {*zoom:}
.clearfix:after{content:"\0020";display:block;height:;clear:both;visibility:hidden}

3.解决合并外边距的问题

  在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是父子关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。
  按照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直Margin的重叠,这个包括相邻元素,嵌套元素,只要他们之间没有线盒(其实就是非空内容),没有间隙(clearance,设置clear以闭合相关方向的浮动 ),没有padding和border将他们分隔开就会发生margin重叠。

  因此要解决margin重叠问题,只要让它们不在同一个BFC就行了,但是对于两个相邻元素来说,意义不大,没有必要给它们加个外壳,但是对于嵌套元素来说就很有必要了,只要把父元素设为BFC就可以了。这样子元素的margin就不会和父元素的margin发生折叠了。

折叠的结果:

两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值( 10px 20px 结果为20px )。
两个相邻的外边距都是负数时,折叠结果是两者绝对值较大的值( -10px -20px 结果是-20px )。
两个外边距一正一负时,折叠结果是两者的相加的和( 10px -20px 结果是10px )。
产生折叠的必备条件:margin必须是边缘毗邻的

而根据w3c规范,两个margin是垂直毗邻的必须满足以下条件:

元素的margin-top与其第一个常规文档流的子元素的margin-top
元素的margin-bottom与其下一个常规文档流的兄弟元素的margin-top
height为auto的元素的margin-bottom与其最后一个常规文档流的子元素的margin-bottom
高度为0并且最小高度也为0,不包含常规文档流的子元素,并且自身没有建立新的BFC的元素的margin-top和margin-bottom
只要触发Block Formatting Contexts的条件 或者是使用非空内容,空隙(clearance),padding和border将他们分隔开margin便不会折叠。

分析一:浮动和绝对定位不与任何元素产生 margin 折叠

原因:浮动元素和绝对定位元素不与其他盒子产生外边距折叠是因为元素会脱离当前的文档流,违反了上面所述的两个margin是邻接的条件同时,又因为浮动和绝对定位会使元素为它的内容创建新的BFC,因此该元素和子元素所处的BFC是不相同的,因此也不会产生margin的折叠。

分析二:inline-block元素与其兄弟元素、子元素和父元素的外边距都不会折叠(包括其父元素和子元素)

inline-block不符合w3c规范所说元素必须是块级盒子的条件,因为规范中又说明,块级盒子的display属性必须是以下三种之一:'block', 'list-item', 和 'table'。

分析三:设置有些属性(如float、position、display)会同时形成BFC与触发hasLayout,或者在>=IE7时也可以设置overflow同时搞定两者。

在IE7以下,只触发(形成)了其中一个,也最好同时触发(形成)另一个,以保证浏览器的兼容。
简单的触发方法:{overflow: hidden;zoom:1;}

如果感觉阅读此文后,有一定的启发和收获,劳驾您推荐下,在此谢过,欢迎留言交流。

【深入BFC】 关于CSS中float布局,清除浮动,和margin合并的原理解析,解开你心中的那些困惑!的更多相关文章

  1. CSS中如果实现元素浮动和清除浮动,看这篇文章就足够了

    浮动基本介绍 在标准文档流中元素分为2种,块级元素和行内元素,如果想让一些元素既要有块级元素的特点也同时保留行内元素特点,只能让这些元素脱离标准文档流即可. 浮动可以让元素脱离标准文档流,可以实现让多 ...

  2. CSS中各种布局的背后(*FC)

    CSS中各种布局的背后,实质上是各种*FC的组合.CSS2.1中只有BFC和IFC,CSS3 中还增加了FFC和GFC. 盒模型(BoxModel) 上图为W3C标准盒模型,另外还有一种IE盒模型(I ...

  3. CSS中float和Clear的使用

    CSS中float和Clear的使用 本文和大家重点讨论一下CSS中Float和Clear属性的使用,一个float对象可以居左或居右,一个设置为float的对象,将根据设置的方向,左移或右移到其父容 ...

  4. CSS(7)--- 通俗讲解清除浮动

    CSS(7)--- 通俗讲解清除浮动 上一篇讲了CSS浮动 博客地址:CSS(6)---通俗讲解浮动(float) 一.理解清除浮动 1.为什么要清除浮动 我们前面说过,浮动本质是用来做一些文字混排效 ...

  5. CSS中的定位与浮动

    CSS中的定位与浮动 本文主要讲述CSS中的三种定位样式static.relative和absolute的区别以及浮动元素的特征. 定位样式 CSS中定位样式position的取值有三个,默认值:st ...

  6. CSS中浮动属性float及清除浮动

    1.float属性 CSS 的 Float(浮动),会使元素向左或向右移动,由于浮动的元素会脱离文档流,所以它后面的元素会重新排列. 浮动元素之后的那些元素将会围绕它,而浮动元素之前的元素将不会受到影 ...

  7. 关于CSS中float的两点心得以及清除浮动的总结

    对一个元素运用float后,该元素将脱离正常文档流,这意味着: 1. 运用float后,该元素不再影响父元素的高度,如果一个元素的所有子元素都是float的话,那么该元素的高度是0,这样后面元素渲染的 ...

  8. 【HTML5&CSS3进阶学习02】Header的实现·CSS中的布局

    前言 我们在手机上布局一般是这个样子的: 其中头部对整个mobile的设计至关重要,而且坑也很多: ① 一般来说整个header是以fixed布局,fixed这个产物在移动端来说本身坑就非常多 ② 在 ...

  9. css中float left与float right的使用说明

    转自:http://www.jb51.net/css/33740.html   脚本之家 No! 要注意以下几点: 1. 浮动元素会被自动设置成块级元素,相当于给元素设置了display:block( ...

随机推荐

  1. 【转】WIN32 控制台程序

    http://blog.csdn.net/houmin0036/article/details/7702236 win32控制台项目指在32位Windows命令提示符(即所谓的dos)环境下运行的应用 ...

  2. poj 3067 - Japan(树状数组)

    先按第一个数从大到小排序,相等的情况下,第二个数按照从大到小排序..... 预处理后,照着树状数组写就行了... 注意:k的最大值应取1000*1000 代码如下: include <cstdi ...

  3. PPC MPC85xx e500学习笔记

    powerpc的内存体系结构 E500内核中包含内存管理单元MMU,其包含两个查找表(TLB0 Transaction Lookside Buffer)和TLB1来实现虚拟地址和物理地址的转化,其中T ...

  4. .Net Core CLI windows安装

    下载官方的msi安装包official MSI installer双击安装就可以了. 默认会安装到C:\Program Files\dotnet\目录下,如果找不到可以用命令 where dotnet ...

  5. 可在广域网部署运行的QQ高仿版 -- GG叽叽V2.4,增加远程协助、桌面共享功能(源码)

    QQ的远程协助.或者说桌面共享是一个非常实用的功能,所以,2.4版本的GG复制了它,而且,GG增强了桌面共享的功能,它可以允许指定要共享桌面的区域,这样,对方就只能看到指定区域的桌面,这对节省流量会非 ...

  6. 前端自动化测试工具doh学习总结(一)

    前言 项目中需要用到前端自动化测试,自己被当作一个探针研究了下目前用的比较多的web自动化测试工具.一开始研究的是的selenium,但由于项目使用了大量的dijit控件,写起testCase来很费劲 ...

  7. 打通移动App开发的任督二脉、实现移动互联创业的中国梦

    年初的两会上,第一次听到克强总理讲到“互联网+”的计划,当时就让我为之感到无比振奋.我个人的理解是:“互联网+”的本质就是要对传统行业供需双方的重构,通过移动互联技术来推动各个行业上的全民创新,促使中 ...

  8. DDD领域驱动设计实践篇之如何提取模型

    需求说明: 省级用户可以登记国家指标 省级用户和市级用户可以登记指标分解 登记国家指标时,需要录入以下数据:指标批次.文号.面积,这里省略其他数据,下同 登记指标分解时,需要录入以下数据:指标批次.文 ...

  9. HTML5触屏版多线程渲染模板技术分享

    前言: 了解js编译原理的屌丝们都知道,js是单线程的,想当年各路神仙为了实现js的多线程,为了解决innerHTML输出大段HTML卡页面的顽疾,纷纷设计了诸如假冒的“多线程“实现,我自己也在写开源 ...

  10. 在Mongoose中使用嵌套的populate处理数据

    假设有如下mongodb的schema定义: drawApply = new Schema({ salesId: { type: Schema.ObjectId, ref: 'sales' }, mo ...