Home  >  Article  >  Web Front-end  >  Learning about hasLayout and Block formatting contexts (Part 2)_html/css_WEB-ITnose

Learning about hasLayout and Block formatting contexts (Part 2)_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-24 11:39:361066browse

BFC layout rules :

  • The internal Boxes will be placed one after another in the vertical direction.
  • The vertical distance of the Box is determined by margin. The margins of two adjacent boxes belonging to the same BFC will overlap
  • The left side of the margin box of each element is in contact with the left side of the containing block border box (for a left-to-right format ation, otherwise the opposite). This is true even if there is float.
  • The BFC area will not overlap with the float box.
  • BFC is an isolated independent container on the page. The sub-elements inside the container will not affect the elements outside. And vice versa.
  • When calculating the height of BFC, floating elements also participate in the calculation.
  • In CSS3, this concept has been changed: http://www.w3.org/TR/css3-box/#block-level0
    In CSS3, BFC is called flow root.
  • 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重叠也是这样的一个道理。
  • Instance analysis of hasLayout and Block formatting contexts

    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>
  • container does not create Block formatting contexts.
  • The 'zoom:1' setting of the container is to trigger hasLayout in IE;
  • The height of the container The value is auto, and the value of 'overflow' is the default 'visible';
  • span1 is an inline element, div1 is a block element in normal flow;
  • div2 is a floating block-level element.
  • 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>
  • container's 'overflow:hidden;' creates the BFC;
  • container's 'overflow:hidden;' 'overflow:hidden;', hasLayout is not triggered in IE6, but hasLayout is triggered in IE7;
  • The height value of the container is 'auto';
  • span1 is an inline element, div1 is a block element in normal flow;
  • div2 is a floating block level element.
  • 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

  • div1 是一个浮动元素,背景是50%的透明
  • div2 的 ‘overflow:hidden;’ 在 IE6 中未触发 hasLayout,但在 IE7 中触发了 hasLayout。
    根据 CSS 2.1 9.5 Floats 中的描述,创建了BFC的元素不能与浮动元素重叠, 所以,div2 应该有一部分被 div1 覆盖。
  • 三. 触发 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 的异同及可能产生的问题

    区别

  • 在 IE8之前的版本中,没有规范中提及的 Block formatting contexts 和 Inline formatting contexts概念,而是用 hasLayout 来达到相似的目的。
  • 在 IE 中可通过设置 ‘width’、’height’、’min-width’、’min-height’、’max-width’、’max-height’、 ‘zoom’、’writing-mode’ 来触发 hasLayout,而这些特性值的设置不能够使元素创建 BFC。
  • 在 IE 中很多元素默认就是拥有布局的,如 IPUNT, BUTTON, SELECT, TEXTAREA 等,但是这些元素在标准中会形成 Inline formatting contexts。
  • 共同点

  • 两者都是决定了对内容如何定位及大小计算的规则。
  • 两者都决定了与其他元素的相互作用的规则。
  • ‘table-cell’ 和 ‘table-caption’ 既是 hasLayout 的元素,又是可以创建 BFC 的元素。
  • 浮动元素,绝对定位元素,inline-block 元素以及除 ‘visible’ 外任意值的 overflow(IE7) 在 IE 中可以触发 hasLayout,同时在标准中,又可以创建BFC。
  • 可能产生的兼容性问题:

    	由于 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

    Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn