目錄
hasLayout与Block formatting contexts的实例分析
hasLayout 和 BFC 的异同及可能产生的问题
首頁 web前端 html教學 hasLayout与Block formatting contexts的学习(下)_html/css_WEB-ITnose

hasLayout与Block formatting contexts的学习(下)_html/css_WEB-ITnose

Jun 24, 2016 am 11:39 AM

BFC布局规则

  • 内部的Box会在垂直方向,一个接一个地放置。
  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  • 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC的区域不会与float box重叠。
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  • 计算BFC的高度时,浮动元素也参与计算。
  • 在CSS3中,对这个概念做了改动:http://www.w3.org/TR/css3-box/#block-level0
    在CSS3中,将BFC 叫做 flow root。
  • 简单示例:
    1.自适应两栏布局
    代码如下:

    	<!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>
    登入後複製

    页面效果图:

    上述示例,正好反映了BFC布局规则:每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
    所以,sidebar虽然存在浮动,但main的左边依然与包含块的左边相接触。

    2.BFC的区域不会与float box重叠。示例如下:

    代码:

    	<!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>
    登入後複製

    页面效果图:

    通过overflow:hidden;触发main的BFC,main区域没有与float的sidebar重叠。说明了BFC的区域不会与float box重叠。

    3.计算BFC的高度时,浮动元素也参与计算。

    	<!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>
    登入後複製

    页面效果图:

    我们通过

    div.wrapper{		width:300px;		border:2px solid #5dc2f6;		overflow:hidden;}
    登入後複製

    overflow:hidden; 触发wrapper的BFC,
    清除box的浮动带来的影响,得到的页面效果图如下:


    因此说明:计算BFC的高度时,浮动元素也参与计算。

    4.清除垂直边距重叠

    代码:

    	<!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>
    登入後複製

    页面效果图如下:

    如图所示,Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。所以,两个div的垂直距离变成了100px,而不是150px了。

    如果我们给第二个div套上一层wrapper,并且触发外层的BFC,那么两个div就不是同一个BFC的两个相邻的Box了,而是变成两个独立的BFC。

    代码:

    	<!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>
    登入後複製

    页面效果图如下:

    垂直边距不再重叠,不是100px,而是150px了。

  • 总结

    以上事例都证明了:BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,所以BFC通过改变自己的宽度,实现不与浮动box有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。
    登入後複製
  • hasLayout与Block formatting contexts的实例分析

    一. 在触发 hasLayout 的元素和创建了 Block Formatting Contexts 的元素中,浮动元素参与高度的计算

    情况1:没有创建 Block formatting contexts 的块级非替换元素,触发了 IE 的 hasLayout。

    分析以下代码:

    	<!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 没有创建 Block formatting contexts。
  • container 的 'zoom:1'设置,是为了触发 IE 中的 hasLayout;
  • container 的高度值为 auto,并且 'overflow' 的值为默认的 'visible';
  • span1是一个行内元素, div1 是一个处于普通流中的块元素;
  • div2 是一个浮动的块级元素。
  • 根据 CSS2.1 规范第 10.6.3部分的高度计算规则,在进行普通流中的块级非替换元素的高度计算时,浮动子元素不参与计算。

    所以,在进行 container 高度计算时,只受 span1 和 div1的影响,应该是它们两个的高度之和,所以最终container 的高度不包括div2的高度。

    页面效果图在各浏览器的效果如下:
    IE6 IE7:

    IE8 Firefox Chrome Safari Opera:

    当去掉container的zoom:1;各浏览器表现一致:

    情况2:创建了 BFC的块级非替换元素,未触发 IE 的 hasLayout。

    代码如下:

    	<!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 的 ‘overflow:hidden;’ 创建了BFC;
  • container 的 ‘overflow:hidden;’,在 IE6 中未触发 hasLayout,但在 IE7中触发了 hasLayout;
  • container 的高度值为 ‘auto’;
  • span1是一个行内元素,div1是一个处于普通流中的块元素;
  • div2是一个浮动的块级元素。
  • 页面效果图如下:

    IE6:

    IE7/IE8/Firefox/Chrome/Safari/Opera

    可见,只要 container 创建了 BFC,其浮动子元素就会参与其高度计算(IE7是由于触发了hasLayout 导致与其它浏览器的效果相同)。

    二.与浮动元素相邻的、触发了 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

    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    Video Face Swap

    Video Face Swap

    使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

    熱門文章

    <🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
    3 週前 By 尊渡假赌尊渡假赌尊渡假赌
    北端:融合系統,解釋
    4 週前 By 尊渡假赌尊渡假赌尊渡假赌
    Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
    3 週前 By 尊渡假赌尊渡假赌尊渡假赌

    熱工具

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神級程式碼編輯軟體(SublimeText3)

    熱門話題

    Java教學
    1670
    14
    CakePHP 教程
    1428
    52
    Laravel 教程
    1329
    25
    PHP教程
    1274
    29
    C# 教程
    1256
    24
    HTML:結構,CSS:樣式,JavaScript:行為 HTML:結構,CSS:樣式,JavaScript:行為 Apr 18, 2025 am 12:09 AM

    HTML、CSS和JavaScript在Web開發中的作用分別是:1.HTML定義網頁結構,2.CSS控製網頁樣式,3.JavaScript添加動態行為。它們共同構建了現代網站的框架、美觀和交互性。

    HTML,CSS和JavaScript的未來:網絡開發趨勢 HTML,CSS和JavaScript的未來:網絡開發趨勢 Apr 19, 2025 am 12:02 AM

    HTML的未來趨勢是語義化和Web組件,CSS的未來趨勢是CSS-in-JS和CSSHoudini,JavaScript的未來趨勢是WebAssembly和Serverless。 1.HTML的語義化提高可訪問性和SEO效果,Web組件提升開發效率但需注意瀏覽器兼容性。 2.CSS-in-JS增強樣式管理靈活性但可能增大文件體積,CSSHoudini允許直接操作CSS渲染。 3.WebAssembly優化瀏覽器應用性能但學習曲線陡,Serverless簡化開發但需優化冷啟動問題。

    HTML的未來:網絡設計的發展和趨勢 HTML的未來:網絡設計的發展和趨勢 Apr 17, 2025 am 12:12 AM

    HTML的未來充滿了無限可能。 1)新功能和標準將包括更多的語義化標籤和WebComponents的普及。 2)網頁設計趨勢將繼續向響應式和無障礙設計發展。 3)性能優化將通過響應式圖片加載和延遲加載技術提升用戶體驗。

    HTML:建立網頁的結構 HTML:建立網頁的結構 Apr 14, 2025 am 12:14 AM

    HTML是構建網頁結構的基石。 1.HTML定義內容結構和語義,使用、、等標籤。 2.提供語義化標記,如、、等,提升SEO效果。 3.通過標籤實現用戶交互,需注意表單驗證。 4.使用、等高級元素結合JavaScript實現動態效果。 5.常見錯誤包括標籤未閉合和屬性值未加引號,需使用驗證工具。 6.優化策略包括減少HTTP請求、壓縮HTML、使用語義化標籤等。

    HTML與CSS vs. JavaScript:比較概述 HTML與CSS vs. JavaScript:比較概述 Apr 16, 2025 am 12:04 AM

    HTML、CSS和JavaScript在網頁開發中的角色分別是:HTML負責內容結構,CSS負責樣式,JavaScript負責動態行為。 1.HTML通過標籤定義網頁結構和內容,確保語義化。 2.CSS通過選擇器和屬性控製網頁樣式,使其美觀易讀。 3.JavaScript通過腳本控製網頁行為,實現動態和交互功能。

    HTML與CSS和JavaScript:比較Web技術 HTML與CSS和JavaScript:比較Web技術 Apr 23, 2025 am 12:05 AM

    HTML、CSS和JavaScript是構建現代網頁的核心技術:1.HTML定義網頁結構,2.CSS負責網頁外觀,3.JavaScript提供網頁動態和交互性,它們共同作用,打造出用戶體驗良好的網站。

    HTML:是編程語言還是其他? HTML:是編程語言還是其他? Apr 15, 2025 am 12:13 AM

    HTMLISNOTAPROGRAMMENGUAGE; ITISAMARKUMARKUPLAGUAGE.1)htmlStructures andFormatSwebContentusingtags.2)itworkswithcsssforstylingandjavascript for Interactivity,增強WebevebDevelopment。

    &lt; strong&gt;,lt; b&gt;有什麼區別標籤和lt; em&gt;,&lt; i&gt;標籤? &lt; strong&gt;,lt; b&gt;有什麼區別標籤和lt; em&gt;,&lt; i&gt;標籤? Apr 28, 2025 pm 05:42 PM

    本文討論了HTML標籤,和和關注其語義與表現用途及其對SEO和可訪問性的影響之間的差異。

    See all articles