走在前端的大道上前端
本篇將本身讀過的相關 盒模型BFC 文章中,對本身有啓發的章節片斷總結在這(會對原文進行刪改),會不斷豐富提煉總結更新。segmentfault
在講 BFC 以前,咱們先來了解一下常見的定位方案,定位方案是控制元素的佈局,有三種常見方案:app
在普通流中,元素按照其在 HTML 中的前後位置至上而下佈局,在這個過程當中,行內元素水平排列,直到當行被佔滿而後換行,塊級元素則會被渲染爲完整的一個新行,除非另外指定,不然全部元素默認都是普通流定位,也能夠說,普通流中元素的位置由該元素在 HTML 文檔中的位置決定。佈局
在浮動佈局中,元素首先按照普通流的位置出現,而後根據浮動的方向儘量的向左邊或右邊偏移,其效果與印刷排版中的文本環繞類似。flex
在絕對定位佈局中,元素會總體脫離普通流,所以絕對定位元素不會對其兄弟元素形成影響,而元素具體的位置由絕對定位的座標決定。spa
Formatting context(格式化上下文) 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。常見的FC有BFC、IFC,還有GFC和FFC。code
那麼 BFC 是什麼呢?orm
BFC 即 Block Formatting Contexts (塊級格式化上下文),它屬於上述定位方案的普通流。blog
一個BFC的範圍 包含建立該上下文元素的全部子元素,但不包括建立了新BFC的子元素的內部元素。這從另外一方角度說明,一個元素不能同時存在於兩個BFC中。由於若是一個元素可以同時處於兩個BFC中,那麼就意味着這個元素能與兩個BFC中的元素髮生做用,就違反了BFC的隔離做用。ip
具備 BFC 特性的元素能夠看做是隔離了的獨立容器,容器裏面的元素不會在佈局上影響到外面的元素,而且 BFC 具備普通容器所沒有的一些特性。
通俗一點來說,能夠把 BFC 理解爲一個封閉的大箱子,箱子內部的元素不管如何翻江倒海,都不會影響到外部。
只要元素知足下面任一條件便可觸發 BFC 特性:
注意:有些文章中說HTML能夠觸發BFC,沒有說body,按照上邊介紹的一個BFC的範圍
和下邊的案例1
來看,HTML能不能觸發不肯定,可是body是能夠的
<style> .p { width:200px; height:50px; margin:50px 0; background-color:red; } </style> <body> <div class="p"></div> <div class="p"></div> </body>
效果圖是:
發生外邊距摺疊,是由於他們 同屬於 body這個根元素
讓 它們 不屬於同一個BFC,就能避免外邊距摺疊:
<style> .wrap { overflow:hidden; } .p { width:200px; height:50px; margin:50px 0; background-color:red; } </style> <body> <div class="p"></div> <div class="wrap"> <div class="p"></div> </div> </body>
效果圖是:
<style> .father { width: 200px; height: 200px; background: skyblue; } .son { width: 100px; height: 100px; background: red; } </style> <body> <div class="father"> <div class="son"></div> </div> </body>
而後,咱們給子元素添加一個margin-top: 50px時
.son { width: 100px; height: 100px; background: red; margin-top: 50px; }
咱們神奇的發現父子元素同時"掉下來了50px",如圖所示
正常狀況下,浮動的元素會脫離普通文檔流,因此下面的代碼裏:
<style> .wrap { border: 1px solid #000; } .inner { float: left; width: 50px; height: 50px; background: #eee; } </style> <body> <div class="wrap"> <div class="inner"></div> </div> </body>
外層的div會沒法包含 內部浮動的div,效果見下圖:
但若是咱們 觸發外部容器的BFC,根據BFC規範 計算BFC的高度時,浮動元素也參與計算,那麼外部div容器就能夠包裹着浮動元素,因此只要把代碼修改以下:
<style> .wrap { border: 1px solid #000; overflow:hidden; } .inner { float: left; width: 50px; height: 50px; background: #eee; } </style> <body> <div class="wrap"> <div class="inner"></div> </div> </body>
就能夠完成如下效果:
要求左側固定300px,右側自適應的佈局
<style> .wrapper, * { padding: 0; margin: 0; } .left { width: 300px; height: 100px; background: red; float: left; } .right { height: 100px; background: skyblue; overflow: hidden; } </style> <div class="wrapper"> <div class="left">left</div> <div class="right">right</div> </div>
原理:BFC元素不會和浮動的元素重疊
參考文章:
10 分鐘理解 BFC 原理
CSS中重要的BFC
淺析CSS裏的 BFC 和 IFC
前端人人都應該理解的盒模型BFC渲染機制