理解 CSS 佈局和塊級格式上下文

来源:https://www.cnblogs.com/wwhhq/archive/2017/12/25/8111546.html
-Advertisement-
Play Games

前言 BFC 的概念始於 CSS2,是個蠻古老的 CSS 話題了,網上也到處能搜到 BFC 的介紹,但是都不夠簡潔。本文系翻譯自 Rachel Andrew 女士的博文 Understanding CSS Layout And The Block Formatting Context,內容足夠簡潔明 ...


前言

BFC 的概念始於 CSS2,是個蠻古老的 CSS 話題了,網上也到處能搜到 BFC 的介紹,但是都不夠簡潔。本文系翻譯自 Rachel Andrew 女士的博文 Understanding CSS Layout And The Block Formatting Context,內容足夠簡潔明瞭。
本文的目的是介紹一些概念,來幫你增強 CSS 碼力。如標題所示,這篇文章主要是講塊級格式上下文(BFC,Block Formatting Context)。你可能沒聽過這個術語,但只要你曾經使用 過CSS 佈局,你就能明白它。理解 BFC 是什麼、它如何工作、如何創建一個 BFC 是非常有用的,這些能幫你更好的理解 CSS 佈局。

這篇文章里,我會通過幾個你會很熟悉的的示例解釋 BFC。我還會告訴你一個新的 display 值,當你理解了 BFC 後可能會很需要這個值。

什麼是 BFC

一個簡單的浮動的示例就能明白 BFC 的行為,在下麵的示例中我們創建一個 box 元素,該元素包裹一段文字和一個浮動的圖片。 如果文字內容多的話文字將環繞著整個浮動圖片,box 的邊框會把他們整個包裹起來。

<div class="outer">
      <div class="float">I am a floated element.</div>
       I am text inside the outer box.
</div>
.outer {
      border: 5px dotted rgb(214,129,137);
      border-radius: 5px;
      width: 450px;
      padding: 10px;
      margin-bottom: 40px;
}
 
.float {
      padding: 10px;
      border: 5px solid rgba(214,129,137,.4);
      border-radius: 5px;
      background-color: rgba(233,78,119,.4);
      color: #fff;
      float: left;  
      width: 200px;
      margin: 0 20px 0 0;
}

cssbfc1225-1.png

文字環繞著浮動元素

但如果把一些文字刪除,就沒有足夠的文字去環繞圖片(浮動元素)了,同時由於浮動元素脫離文檔流,box 元素的邊框高度就會隨文字的減少而降低。

cssbfc1225-2.png

沒有足夠的文字,box 元素邊框的高度就會低於浮動元素的高度

之所以會發生這種情況是由於當我們浮動一個元素後,box 元素仍然保持原來的寬度,是文字所占的空間縮短了以給浮動元素騰出位置,這就是為什麼背景和邊框能夠看起來包裹住了浮動元素。

我們通常會使用兩種不同的方式來解決這個問題,一種是使用 clear hack,就是在 文字和圖片的下方插入一個 div 並將它的 CSS clear 屬性設值為 both。另外一種方法是使用 overflow 屬性 ,把它設值成非預設值 visible 的值。

.outer {
      overflow: auto;
}

cssbfc1225-3.png

使用 overflow: auto 後 box 就能包裹浮動元素了

overflow 之所以能夠有效是因為當它的是是非 visible 時會創建一個 BFC,而 BFC 的功能之一就是包裹浮動元素。

BFC 是佈局中的迷你佈局

你可以把 BFC 當做你頁面中的一塊小佈局,當一個元素被創建成 BFC 後,它其中的所有元素都會被它包裹。正如我們所見,當 box 元素變成 BFC 後,它其中的浮動元素就再也沒能突破它的底部。除此之外,BFC 還有一些有用的功能。

BFC 可以阻擋外邊距疊加(margins collapsing)

理解外邊距疊加是另外一個被低估的 CSS 技巧。在接下來的示例里,我創建了一個背景灰色的 div,這個 div 含有兩個段落,div 元素的 margin-bottom 為 40px,同時每個段落都有 20px 的 margin-top 與 margin-bottom。

.outer {
       background-color: #ccc;
      margin: 0 0 40px 0;
}
 
p {
      padding: 0;
      margin: 20px 0 20px 0;
      background-color: rgb(233,78,119);
      color: #fff;
}
 ```


由於 p 元素的邊緣與 outer 元素的邊緣之間沒有任何東西,所以 outer 與 p 的 margin 會疊加,p 會與 outer 的頂部與底部齊平,p 對外的 margin 似乎與 outer 的 margin 合併了,使我們無法在段落的上下看到 outer 的灰色背景。

![cssbfc1225-4.png](//upload-images.jianshu.io/upload_images/5925829-a3ce76a02b036b6f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


由於 margin collapse(外邊距疊加),我們看到 outer 內部上下沒有灰色背景

如果我們把 outer 元素變成 BFC,它就可以包裹住 p 以及 p 的 margin,外邊距不會發生疊加,outer 元素內部就會出現由 p 元素的 margin 頂出來的上下灰色背景。

.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto;
}
```
cssbfc1225-5.png

建立 BFC 後,外邊距不再疊加

一旦 BFC 建立,它就會阻止它內部的元素逃離突破它。

一個 BFC 會停止去環繞浮動元素

你可能很熟悉 BFC 的這個特性,我們在有浮動元素的列類型佈局中常用到。如果一個元素創建了 BFC,它就不會去環繞(或者說包裝?)任何浮動元素。看下麵這個示例:

<div class="outer">
      <div class="float">I am a floated element.</div>
      <div class="text">I am text</div>
</div>

class 名為 float 的元素將會浮動在佈局的左側,class 名為 text 的 div 元素將會在它後面並環繞它。
cssbfc1225-6.png

文字環繞著浮動元素

我們可以通過給 text 元素建立 BFC 來阻擋這種環繞行為。

.text {
      overflow: auto;
}

cssbfc1225-7.png

text 元素建立 BFC 後就不再環繞浮動元素了

該方法也是我們創建浮動佈局的基本方式。還需註意的是浮動一個元素時也會給該元素創建 BFC,也就是說此時 .float 與 .text 都是 BFC,這也是無論右側高度低於還是高於左側兩者都不會互相圍繞的原因。

創建一個 BFC 的常用方式

除了使用 overflow 外, 一些其他的 CSS 屬性也可以創建 BFC,比如上面我們所見,浮動一個元素也可以為該元素創建 BFC,浮動元素會包裹它內部的所有元素。還有以下幾種方式可以創建 BFC:

使用 position: absolute 或者 position: fixed。

使用 display: inline-block、display: table-cell 或者 display: table-caption,其中 table-cell 和 table-caption是表格相關 HTML 元素的對應預設 CSS 值,所以當你創建表格每個表格單元都會自動創建 BFC。

另外當使用 multi-column layout (多列佈局)時使用 colum-span: all 也可以創建 BFC。Flex(彈性) 和 Grid(網格) 佈局中的元素也會自動創建類似 BFC 的機制,只是它們被稱為 Flex Formatting Context(彈性格式上下文)和 Grid Formatting Context(網格格式上下文)。這反映了它們所參與的佈局類型。一個 Block Formatting Context(塊級格式上下文)表明他內部的元素參與了塊級佈局,一個 彈性格式上下文意味著它內部的元素參與了彈性佈局。在實踐中,這幾種佈局的結果是相似的,浮動元素會被包裹、外邊距不會疊加。

創建 BFC 的新方式

使用 overflow 或其他的方法創建 BFC 時會有兩個問題。第一個是這些方法本身是有自身的設計目的的,所以在使用它們創建 BFC 時會可能產生副作用。例如使用 overflow 創建 BFC 後在某些情況下你可能會看到出現一個滾動條或者元素內容被削減。這是由於 overflow 屬性是設計被用來讓你告訴瀏覽器如何定義元素的溢出狀態的。瀏覽器執行了它最基本的定義。

另一個問題是,即使在沒有出現副作用的情況下,使用 overflow 也可能會使另一個開發人員感到困惑。他們可能會各種猜想:這裡為啥要把 overflow 的值設為 auto 或 scroll?原開發人員做這個意義何在?原開發人員是想讓這裡出現滾動條嗎?

最安全的做法應該是創建一個 BFC 時不會有任何副作用,它內部的元素都安安全全的呆在這個小佈局里,這種方法不會引起任何意想不到的問題,也可以讓開發者意圖清晰。CSS 工作組也十分認同這種想法,所以他們定製了一個新的屬性值:display: flow-root。

你可以使用 display: flow-root 安全的創建 BFC 來解決本文中提到的各種問題,包括:包裹浮動元素、阻止外邊距疊加、阻止環繞浮動元素。
cssbfc1225-8.png

caniuse 上 display: flow-root 各瀏覽器支持情況

瀏覽器對該屬性值的支持目前還是有限的,如果你覺得這個屬性值很方便,請投票去讓 Edge 也支持它。不過無論如何,你現在應該已經理解了什麼是 BFC,以及如何使用 overflow 或其他方法來包裹浮動,以及知道了 BFC 可以阻止元素去環繞浮動元素,如果你想使用彈性或網格佈局可以在一些不支持他們的瀏覽器中使用 BFC 的這些特性做降級處理。

理解瀏覽器如何佈置網頁是非常基礎的。 雖然有時看起來無關緊要,但是這些小知識可以加快創建和調試 CSS 佈局所需的時間。

版權屬於: 前端記錄

原文地址: http://www.ferecord.com/understanding-css-layout-block-formatting-context.html

轉載時必須以鏈接形式註明原始出處及本聲明。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 分享一個開源的項目 share device 項目地址:https://github.com/sunshine4me/ShareDevicePublish/tree/win7-x64 首先選擇對應系統的下載包,如下圖: 註意: 運行 ShareDevice.exe 運行 ShareDevice.ex ...
  • 2015 年是銘心刻骨的一年,這一年,股市崩盤,千古跌停,手裡的兩個票更是挨了腰斬,寶寶心裡苦。同是這一年,ES6 標準落地,作為一名前端開發,寶寶心裡又樂開了花。 ...
  • 廢話少說 上鏈接 angular 升級指南 ...
  • 前言 在JSBridge實現後,前端網頁與原生的交互已經通了,接下來就要開始規劃API,明確需要提供哪一些功能來供前端調用。 但是在這之前,還有一點重要工作需要做: __明確H5與Native的職責劃分,確定哪一些功能可以由H5實現,哪一些功能只能由原生實現__ Native與H5職責劃分 使用Hy ...
  • 第一步處理rule為字元串,直接返回一個包裝類,很簡單看註釋就好了。 test 然後處理test、include、exclude,如下: checkResourceSource直接看源碼: 這個用於檢測配置來源的唯一性,後面會能看到作用,同樣作用的還有checkUseSource方法。 隨後將三個參 ...
  • Tips:寫到這裡,需要對當初的規則進行修改。在必要的地方,會在webpack.config.js中設置特殊的參數來跑源碼,例如本例會使用module:{rules:[...]}來測試,基本上測試參數均取自於vue腳手架(太複雜的刪掉)。 下麵兩節的主要流程圖如下: 在進入compile方法後,迎面 ...
  • 解釋說明: 先將字元串轉化為數組,然後將其轉化為小寫,這裡用到str.toLowerCase()和str.split(" "),split分割一定要用空格隔開,然後用for迴圈遍曆數組中每個元素,將每個元素的首字母賦值給變數char,再用toUpperCase()函數將首字母大寫,再將每個元素重新... ...
  • JavaScript本身可通過charCodeAt方法得到一個字元的Unicode編碼,並通過fromCharCode方法將Unicode編碼轉換成對應字元。 但charCodeAt方法得到的應該是一個16位的整數,每個字元占用兩位元組。在網路上傳輸一般採用UTF 8編碼,JavaScript本身沒有 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...