理解 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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...