淺析BFC和IFC

来源:http://www.cnblogs.com/Candybunny/archive/2016/12/26/6222939.html
-Advertisement-
Play Games

1. 為什麼會有BFC和IFC 首先要先瞭解兩個概念:Box和formatting context; Box:CSS渲染的時候是以Box作為渲染的基本單位。Box的類型由元素的類型和display屬性決定,box的類型分為block-level box 和inline-level box(不包括cs ...


1. 為什麼會有BFC和IFC

  首先要先瞭解兩個概念:Box和formatting context;   Box:CSS渲染的時候是以Box作為渲染的基本單位。Box的類型由元素的類型和display屬性決定,box的類型分為block-level box 和inline-level box(不包括css3的時候)。不同類型的box參與不同類型的formatting context佈局。   block-level box:display 屬性為 block, list-item, table 的元素,會生成 block-level box。並且參與 block fomatting context;    inline-level box:display 屬性為 inline, inline-block, inline-table 的元素,會生成 inline-level box。並且參與 inline formatting context;   run-in box: css3 中才有,即GFC,FFC     Formatting context:每個渲染區域用formatting context表示。它決定了其子元素將如何定位,以及和其他元素的關係和相互作用        BFC和IFC則可以理解為不同渲染區域遵循的不同規則。

2. 什麼是BFC和IFC

  • BFC

  1. 什麼時候會產生BFC:

  1. float is not none
  2. position is absolute & fixed
  3. display is table-cell,table-caption,inline-block,flex,inline-flex
  4. overflow is not visible

  2. 特性:

o   內部的Box會在垂直方向,一個接一個地放置。 o   Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。 o   BFC的區域不會與float box重疊 o   BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此。 o   計算BFC的高度時,浮動元素也參與計算。  

  3. 作用:

    通常會用BFC來解釋以下2個問題:     1. margin collapse:上下margin會合併(這裡不過多闡述,可參考鏈接[3])     2. contain float:      其中的一種解決方法:overflow:hidden ,創建新的BFC,可以包含float元素,父元素就有高度值了

    此處闡述一下自己的理解:如果父元素只包含浮動元素,因為浮動元素是不包含在正常流的,浮動孩子將會脫離頁面的常規流,因此父元素相當於不包含任何元素,高度為0。

    而BFC裡面有兩條規則:
    1、BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此。
    2、計算BFC的高度時,浮動元素也參與計算
    overflow:hidden會產生新的BFC,子元素的被包含在父元素的BFC中,因此父元素不受子元素影響,恢復常規佈局,遵循BFC規則,同時計算高度時,父元素的高度會將浮動元素算進來,因此父元素有了高度。

    不過這裡要闡述一件事就是高度塌陷只出現在父元素包含且只包含浮動元素的時候:

    看圖:在父元素沒有明確定義height的時候,如果只包含浮動元素,父元素會出現高度塌陷的問題。(其中的解決方法主要有添加偽元素clear:both,設置父元素height,設置父元素overflow:hidden等方式)

下圖:當父元素內部有非float元素時(clear:both的原理)   
  • IFC
  IFC也是一種佈局規則,inline元素和inline-block符合IFC的佈局規則。在IFC佈局中重點關註一下line box。

       在IFC中,內聯元素在水平方向上一個接一個的排布,其中,容器之間水平方向上的margin,padding,border方向上是好使的。他們垂直方向上有很多種對其方式,比如居底部或頂端對齊,或者基線對齊。他們對齊完了之後形成的這個四方塊兒區域,叫做一個line box(行框)。

  一個line box的寬度由包含它的元素的寬度和包含它的元素裡面有沒有float元素來決定,而高度由內部元素中實際高度最高的元素而計算出來。

  line box的高度是足夠高來包含他內部的容器們的,也可能比它包含的容器們都高(比如在基線對齊的時候),當他包含的內部容器的高度小於line box的高度的時候,內部容器的垂直位置由自己的vertical這個屬性來確定。當內部的容器盒子太多了一個line box裝不下來,他們折行之後會變成兩個或者多個line box, line box們相互之間垂直方向不能分離,不能重疊。

  一般來說,line box的左邊緣挨著包含它的元素的左邊緣,並且右邊緣挨著包含它的元素的右邊緣,浮動元素會在包含他們的元素的邊緣和line box的邊緣之間,所以雖然在同一個IFC下的line box們通常擁有相同的寬度(就是包含他們的容器的寬度),但是也會因為浮動元素的搗亂,導致line box們的可用寬度產生了變化不一樣了。在同一個Ifc下的line box們的高度也會不一樣(比如說,一個line box里有個比較大的image,他就高了)。

  如果一個line box 里的內聯元素們的寬度總和小於這個line box的寬度,那麼他們在這個line box里的水平方向的排布方式由 text-align這個屬性來決定,如果這個屬性被設置成了“justify”,可以使這些盒子在剩餘空間內拉伸(除了inline-table 和 inline-block的元素)

  在一個line box中,當他包含的內部容器的高度小於line box的高度的時候,內部容器的垂直位置由自己的vertical這個屬性來確定。那麼,我們設想一下,如果手動創建一個IFC的環境,讓line box的高度是包含塊的高度的100%,讓line box內部的元素使用vertical-align:middle,就可以實現垂直居中。

  一個line box的高度由內部元素中實際高度最高的元素而計算出來。所以,我們在line box中插入一個高度100%的inline-block元素。則會把整個line box撐高直到包含塊的100%.   當內聯元素的寬度超過了line box的寬度,那麼它會折行分裂成了幾個line box,如果這個元素裡面的內容不可以折行,例如只有一個字,或者white-space設置了nowrap/pre。那麼內聯元素會溢出line box。   當一個內聯元素分裂時,分裂處的 margins, borders 和 padding不會有任何視覺效果(或者其他任何分裂,只要是有多個line box)。   line box 的生存條件是在IFC中並且包含inline-level元素,如果line box里沒有文本,空白,換行符,內聯元素,也沒有其他的存在IFC環境中的元素,(如inline-block,inline- table,images等),將會被視為零高度,也將會被視為沒有意義。   補充:在IFC的環境中,是不能存在block-level元素的,如果將block-level元素插入到IFC中,那麼此IFC將會被破壞掉, 而block-level元素前的元素和block-level元素後的元素將會各自自動產生一個匿名容器其包圍,這個匿名的容器內部環境將是一個新的 IFC。


  此處補充一些自己對於IFC高度計算的理解:主要是line-height和height

  IFC中height的計算方式:line height表示高度

  *line-height如果沒有顯式聲明,那麼繼承父元素的line-height;如果顯示聲明瞭,則用聲明後的高度(vertical-align的時候參考的邊界值)

  css中的line-height表示line space(行間差值) + font-size

看下圖:

 

可以得到:1.height對inline元素並不起作用 2.只有設置了line-height的inline元素才會參與vertical-align的排列規則(這裡個人分析是因為只有設置了高度,vertical-align時才能計算到邊界值,從而對其進行排列,否則預設都是baseline規則)

此處可以再看一個例子:

 

 這個地方設置第二個元素的line-height是80,而父元素的line-height是100,vertical-align預設是相對於父元素的排列。首先中線的位置是一半,所以(100/2)-(80/2)=10,第二個元素下移了10px。 更多關於vertical-align的知識可以參考[6],[7]。   參考文獻: [1]http://www.cnblogs.com/weinan/p/3665766.html
[2]https://www.w3ctech.com/topic/865 [3]https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context [4]https://www.sitepoint.com/understanding-block-formatting-contexts-in-css/ [5]https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Visual_formatting_model
[6]http://phrogz.net/css/vertical-align/index.html [7]http://christopheraue.net/2014/03/05/vertical-align/
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • transition過渡 transition-duration:; 運動時間 transition-delay:; 延遲時間 transition-timing-function:; 運動形式 ease 逐漸變慢 (預設) linear 勻速 ease-in 加速 ease-out 減速 ease ...
  • (註冊博客好久了,一直沒捨得添磚加瓦,主要是每次想寫點東西的時候,隨便搜一搜發現都比我總結的都要好,甚感尷尬,但是總是要開始的,所以這就是我的第一篇博客,也絕不會是最後一篇,廢話不多說,直接入正題) iframe和彈窗這些詞對於js高手來說都是耳熟能詳的東西,作為一個新人來說,還在學習階段的我就在工 ...
  • 1、把其他的數據類型轉換為number類型 Number()->嚴格 parseFloat/parseInt ->非嚴格 isNaN(value) 如果value值不是數字類型的,它是首先調用Number轉換為數字類型然後在判斷是否為有效的數字 例如: Number("12px"); ->NaN p ...
  • 1.js函數語法 2.js函數參數在內部是以一個數組的方式表示的。 3.js函數沒有重載。 ...
  • js中的語法大量借鑒於C以及其他類C語言(Java,Perl)。 js中一切(變數、函數名、操作符等等)都區分大小寫。 ...
  • 1. 標題 : <h1> - <h6> 2. 分割線 : <hr> 3. 加粗: <strong> 4. 斜體: <em> <i> 5. 段落 : <p> 6. 換行 : <br/> 7. 超鏈接: <a> href 屬性指定鏈接的地址 target ( 目標 ):_self ( 當前頁面打開 ) ...
  • 最近使用 "GitHub Pages" + "Jekyll" 搭建了 "個人博客" ,作為一名重度音樂患者,博客裡面可以不配圖,但是不能不配音樂啊。 遂在博客裡面引入了 網易雲模塊 ,這裡要感謝網易雲的分享機制,對開發者非常友好: 1.每首歌曲都支持生成外鏈播放器,且可以自定義顯示尺寸: 2.網易雲 ...
  • 說到浮動之前,先說一下CSS中margin屬性的兩種特殊現象 1, 外邊距的合併現象: 如果兩個div上下排序,給上面一個div設置margin-bottom,給下麵一個div設置margin-top,那麼兩個margin會發生合併現象,合併以後的值較大的那個。 對於這種現象一般不用處理。 2,ma ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...