BFC layout rules :
Simple example:
1. Adaptive two-column layout
The code is as follows:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> body{ width:350px; position:relative; } div.sidebar{ float:left; width:100px; height:200px; background-color:#9deaf1; } div.main{ height:300px; background-color:#5dc2f6; } </style> </head> <body> <div class="sidebar"></div> <div class="main"></div> </body> </html>
Page rendering:
The above example exactly reflects the BFC layout rules: the left side of the margin box of each element touches the left side of the containing block border box (for left-to-right formatting, otherwise the opposite). This is true even if there is float.
So, although the sidebar floats, the left side of main is still in contact with the left side of the containing block.
2. The BFC area will not overlap with the float box. The example is as follows:
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> body{ width:350px; position:relative; } div.sidebar{ float:left; width:100px; height:200px; background-color:#9deaf1; } div.main{ height:300px; background-color:#5dc2f6; overflow:hidden; } </style> </head> <body> <div class="sidebar"></div> <div class="main"></div> </body> </html>
Page rendering:
Trigger the main BFC through overflow:hidden; and the main area does not overlap with the float sidebar. It shows that the BFC area will not overlap with the float box.
3. When calculating the height of BFC, floating elements also participate in the calculation.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> div.wrapper{ width:300px; border:2px solid #5dc2f6; } div.box{ width:100px; height:200px; background-color:#9deaf1; border:2px solid #5dc2f6; float:left; } </style> </head> <body> <div class="wrapper"> <div class="box"></div> <div class="box"></div> </div> </body> </html>
Page rendering:
We trigger wrapper’s BFC through
div.wrapper{ width:300px; border:2px solid #5dc2f6; overflow:hidden;}
overflow:hidden; and
clear the box The resulting page rendering is as follows:
Therefore, when calculating the height of BFC, floating elements also participate in the calculation.
4. Clear vertical margin overlap
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> div.box{ width:100px; height:100px; background-color:#9deaf1; border:2px solid #5dc2f6; } div.m50{ margin-bottom:50px; } div.m100{ margin-top:100px; } </style> </head> <body> <div class="box m50"></div> <div class="box m100"></div> </body> </html>
The page rendering is as follows:
As shown in the picture As shown, the vertical distance of the Box is determined by the margin. The margins of two adjacent boxes belonging to the same BFC will overlap. Therefore, the vertical distance between the two divs becomes 100px instead of 150px.
If we put a wrapper on the second div and trigger the outer BFC, then the two divs are not two adjacent boxes of the same BFC, but become two Independent BFC.
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> div.box{ width:100px; height:100px; background-color:#9deaf1; border:2px solid #5dc2f6; } div.wrapper{ overflow:hidden; } div.m50{ margin-bottom:50px; } div.m100{ margin-top:100px; } </style> </head> <body> <div class="box m50"></div> <div class="wrapper"> <div class="box m100"></div> </div> </body> </html>
The page rendering is as follows:
The vertical margins no longer overlap, it is not 100px, but 150px.
Summary
以上事例都证明了:BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,所以BFC通过改变自己的宽度,实现不与浮动box有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。
1. In the elements that trigger hasLayout and Among elements with Block Formatting Contexts created, floating elements participate in height calculation
Case 1: Block-level non-replacement elements without Block formatting contexts are created, triggering IE's hasLayout.
Analyze the following code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout 和 BFC</title> <style> div.wrapper{ width:300px; } div#container{ background-color:#9deaf1; zoom:1; } span#span1{ background-color:#5dc2f6; } div#div1{ width:150px; height:50px; background-color:#0576b0; } div#div2{ float:left; background-color:#4dd5b3; } </style> </head> <body> <div class="wrapper"> <div id="container"> <span id="span1">simple text</span> <div id="div1">in flow</div> <div id="div2">float:left</div> </div> </div> </body> </html>
According to the height calculation rules in Section 10.6.3 of the CSS2.1 specification, when calculating the height of block-level non-replaced elements in normal flow, floating child elements do not participate in the calculation.
So, when calculating the height of the container, it is only affected by span1 and div1, and should be the sum of their two heights, so the final height of the container does not include the height of div2.
The page renderings in each browser are as follows:
IE6 IE7:
IE8 Firefox Chrome Safari Opera:
When the container is removed zoom: 1; The performance of each browser is consistent:
Case 2: A BFC block-level non-replacement element is created, and IE's hasLayout is not triggered.
The code is as follows:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout 和 BFC</title> <style> div.wrapper{ width:300px; } div#container{ background-color:#9deaf1; overflow:hidden; } span#span1{ background-color:#5dc2f6; } div#div1{ width:150px; height:50px; background-color:#0576b0; } div#div2{ float:left; background-color:#4dd5b3; } </style> </head> <body> <div class="wrapper"> <div id="container"> <span id="span1">simple text</span> <div id="div1">in flow</div> <div id="div2">float:left</div> </div> </div> </body> </html>
The page rendering is as follows:
IE6:
IE7/IE8/Firefox/Chrome/Safari/Opera
It can be seen that as long as the container creates a BFC, its floating child elements will participate in its height calculation (IE7 has the same effect as other browsers because hasLayout is triggered).
二.与浮动元素相邻的、触发了 hasLayout 的元素或创建了 BFC 的元素,都不能与浮动元素相互覆盖。
与浮动元素相邻的、触发了 hasLayout 的元素或创建了 Block formatting contexts的元素,都不能与浮动元素相互覆盖。如果浮动元素的两侧有足够的空间放置该元素,则元素会紧邻浮动元素放置,必要时,该元素的宽度将会被压缩。否则它们可能会定位到浮动元素的下方。
情况1:没有创建BFC的块级非替换元素,触发了 IE 的 hasLayout。
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout 和 BFC</title> <style> div#container{ border:2px solid #ddd; width:300px; height:150px; background:url("http://images0.cnblogs.com/ blog2015/790006/201508/041827351894332.png") repeat; } div#div1{ width:100px; height:100px; background-color:#9deaf1; float:left; filter:alpha("opacity=50"); opacity: 0.5; } div#div2{ background-color:green; zoom:1; } </style> </head> <body> <div id="container"> <div id="div1"> Float Block </div> <div id="div2"> 怀才就象怀孕,时间久了会让人看出来。 </div> </div> </body> </html>
IE6:
IE7/IE8
Firefox/Chrome/Safari/Opera
根据 CSS 2.1 9.5 Floats 中的描述,浮动元素会覆盖普通流中的块容器。所以,div2 应该有一部分被 div1 覆盖。
情况2:创建了 BFC的块级非替换元素,未触发 IE 的 hasLayout。
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout 和 BFC</title> <style> div#container{ border:2px solid #ddd; width:300px; height:150px; background:url("http://images0.cnblogs.com/ blog2015/790006/201508/041827351894332.png") repeat; } div#div1{ width:100px; height:100px; background-color:#9deaf1; float:left; filter:alpha("opacity=50"); opacity: 0.5; } div#div2{ background-color:green; overflow:hidden; } </style></head><body> <div id="container"> <div id="div1"> Float Block </div> <div id="div2"> 怀才就象怀孕,时间久了会让人看出来。 </div> </div></body></html>
Firefox/Chrome/Safari/Opera:
IE6:
IE7/IE8
三. 触发 hasLayout 的元素和创建了 BFC的元素不会与它们的子元素发生外边距折叠
情况1:没有生成BFC的块级非替换元素,触发了 IE 的 hasLayout。
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hasLayout和BFC</title> <style> div.box{ width:100px; height:100px; background-color:#9deaf1; border:2px solid #5dc2f6; } div.wrapper{ zoom:1; } div.m50{ margin-bottom:50px; } div.m100{ margin-top:100px; } </style> </head> <body> <div class="box m50"></div> <div class="wrapper"> <div class="box m100"></div> </div> </body> </html>
根据 CSS 2.1 8.3.1 Collapsing margins 第一条,两个相邻的普通流中的块框在垂直位置的空白边会发生折叠现象。
通过zoom:1;在IE中触发了hasLayout,所以,垂直边距不重叠,为150px。
而BFC未触发,所以垂直边距重叠,为100px;
IE6/IE7:
IE8/Firefox/Chrome/Safari/Opera:
情况2:生成 BFC的块级非替换元素,未触发 IE 的 hasLayout。
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BFC</title> <style> div.box{ width:100px; height:100px; background-color:#9deaf1; border:2px solid #5dc2f6; } div.wrapper{ overflow:hidden; } div.m50{ margin-bottom:50px; } div.m100{ margin-top:100px; } </style> </head> <body> <div class="box m50"></div> <div class="wrapper"> <div class="box m100"></div> </div> </body> </html>
IE6:
IE7/IE8/Firefox/Chrome/Safari/Opera:
IE7此时触发了hasLayout,但IE6没有触发hasLayout。
区别
共同点
可能产生的兼容性问题:
由于 hasLayout 和 BFC是对一类事物的不同理解,并且他们的启用条件不尽相同,因此如果一个元素设计时,在 IE 早期版本中触发了 hasLayout ,但在其他浏览器中又没有创建BFC,或者相反,一个元素在 IE 早期版本中没有触发 hasLayout ,在其他浏览器中却创建了 BFC(如设置了 ‘overflow:hidden’ ),将导致页面布局的重大差异。
解决方案
仅当一个元素即在 IE 早期版本中触发了 hasLayout,又在其他浏览器中创建了BFC时,才能避免上述问题的发生。即同时启用上述两者以保证各浏览器的兼容,或者相反,两者皆不启用。 使元素即生成了BFC,又触发了 hasLayout 对于触发 hasLayout 的元素,通过 CSS 设置,使它产生BFC; 生成 BFC但是没有触发 hasLayout 的元素,通过设置 ‘zoom:1’,使其触发 hasLayout。 使元素即没有触发 hasLayout,又没有创建 BFC。
如有错误或者不足的地方,还望指正!----妙瞳
文章参考资料:
http://w3help.org/zh-cn/causes/RM8002