1. BFC(Block Formatting Context)直译为“块级格式化范围,环境,上下文”。
BFC的定义:是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。
Mozilla Developer Center 对它的定义如下:
“一个块级格式化范围是CSS对一个页面进行可视化渲染时产生的区域,在这个区域中会产生被渲染的盒子模型、以及相互影响的浮动元素。”
2.如何产生BFC:当一个HTML元素满足下面条件的任何一点,都可以产生Block Formatting Context:
float的值不为none。
overflow的值不为visible。
display的值为table-cell, table-caption, inline-block中的任何一个。
position的值不为relative和static。
3.BFC的作用
只要把父元素设为BFC就可以清理子元素的浮动了,最常见的用法就是在父元素上设置overflow: hidden样式,对于IE6加上zoom:1就可以了(IE Haslayout)。
照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直Margin的重叠,这个包括相邻元素,嵌套元素,只要他们之间没有阻挡(例如边框,非空内容,padding等)就会发生margin重叠。
4.要清除一个块级元素范围内的浮动,也就是让这个块级元素成为一个新的独立的BFC,可以采取上面的方法,例如使这个块级元素的overflow:hidden。
例如下面的效果:
<style>
*{ padding:0; margin:0; }
#red, #yellow, #orange, #green { width:100px; height:100px; float:left; }
#red { background-color:red; }
#yellow { background-color:yellow; }
#orange { background-color:orange; }
#green { background-color:green; }
</style>
<body>
<div id="c1">
<div id="red"></div>
<div id="yellow"></div>
</div>
<div id="c2">
<div id="orange"></div>
<div id="green"></div>
</div>
<p>Here is the text!</p>
</body>
该段代码本意要形成两行两列的布局,但是由于#red,#yellow,#orange,#green四个div在同一个布局环境中,因此虽然它们位于两个不同的div(#c1和#c2)中,但仍然不会换行,而是一行四列的排列。若要使之形成两行两列的布局,就要清除#c1和#c2中的浮动。可以添加下列代码到css中:
#c1{ overflow:hidden; }
#c2 { overflow:hidden; }
再例如下面的这个效果:
<style>
* { padding:0; margin:0; }
#left { width:100px; height:100px; background-color:red; float:left; }
#right { height:200px; width:200px; background-color:yellow; }
</style>
<body>
<div id="left"></div>
<div id="right"></div>
</body>
结果是普通的#right元素被浮动的#left元素所覆盖了。要避免这个情况,就是让#right形成新的BFC,给#right一个overflow:hidden。代码如下:
#right { height:200px; width:200px; background-color:yellow; overflow:hidden; }
注意#right虽然形成新的BFC,但它的margin还是会被浮动元素所覆盖。(外边距折叠的问题一会说)
--------------------------- 华丽丽的分割线 ----------------------------
关于外边距折叠的问题:
外边距折叠是浏览器渲染时候的一个特性,而非bug。
发生外边距折叠的条件:
两个元素在垂直方向上有相邻的外边距时。
·当兄弟元素时,元素间的距离折叠;(见例1代码)
·当父子元素时,子元素的外边距折叠到父元素上。(见例2代码)
发生外边距折叠时的计算法则:
·两个元素的外边距都是正值时,取较大者;
·两个元素的外边距一正一负时,取两者之和。
例1代码如下:
<style>
* { padding:0; margin:0; }
#d1 { width:100px; height:100px; background-color:red; margin:50px; }
#d2 { width:200px; height:200px; background-color:pink; margin:30px; }
</style>
<body>
<div id="d1"></div>
<div id="d2"></div>
</body>
#d1和#d2是兄弟元素,外边距分别为50px和30px,二者在垂直方向上有相邻外边距,#d1的下边距50px和#d2的上边距30px相邻,由于折叠,二者在垂直方向上的边距不是80px,而是50px。(取较大者)
例2代码如下:
<style>
* { padding:0; margin:0; }
#d1 { width:100px; height:100px; background-color:red; margin:50px; }
#d2 { width:200px; height:200px; background-color:pink; margin:30px; }
</style>
<body>
<div id="d2">
<div id="d1"></div>
</div>
</body>
#d1和#d2是父子元素,外边距分别为50px和30px,二者在垂直方向上有相邻外边距,#d1的上边距50px和#d2的上边距30px相邻,由于子元素#d1的上边距会与父元素#d2的上边距折叠,因此实际上边距为50px,也就是父元素的上边距距离浏览器上边框的距离是50px。而子元素和父元素的上边框齐平。(子元素外边距折叠到父元素上)
如果不希望发生外边距的折叠:
·在两相邻的外边距之间加入任意内容(不为空的元素、不为0的padding或border值)
·为两个产生边距折叠元素中的任一个添加定义:
【overflow:hidden(只用于父子情况的父元素上)】
【display:inline-block】
【float:left|right】
--------------------------- 华丽丽的分割线 ----------------------------
如何创建BFC: ·
·根元素:html body
·浮动元素:float:left float:right
·绝对定位元素:position:absolute position:fixed
·以下三种布局类型的元素:display:inline-block|table-cell|table-caption
·溢出内容不直接显示的元素:overflow:hidden|scroll|auto