CSS之BFC、IFC、GFC和FFC

來源:互聯網
上載者:User

前言                                
  盒子模型作為CSS基礎中的基礎,曾一度以為掌握了IE和W3C標準下的塊級盒子模型即可,但近日在學習行級盒子模型時發現原來當初是如此幼稚可笑。本文嘗試全面敘述塊級、行級盒子模型的特性。作為近日學習的記錄。

何為盒子模型?                             
  盒子模型到底何方神聖居然可以作為CSS的基礎。聞名不如見面,上圖了喂!

  再來張切面圖吧!

  下面我們以 <div></div> 為栗子。 <div></div> 標籤被瀏覽器解析後會產生div元素並添加到document tree中,但CSS作用的對象並不是document tree,而是根據document tree產生的render tree,而盒子模型就是render tree的節點。
  * 注意: 
  * 1. CSS作用的是盒子(Box), 而不是元素(Element);
  * 2. JS無法直接操作盒子。

  盒子模型的結構
  由於塊級盒子在驗證效果時幹擾資訊更少,便於理解盒子模型,因此下面將以塊級盒子模型來講解。
  注意: 行級盒子模型與塊級盒子模型結構一致,只是行級盒子在此基礎上有自身特性而已。
  從上面兩幅圖說明盒子模型其實就是由以下4個盒子組成:
  1. content box:必備,由content area和4條content/inner edge組成;
  2. padding box:可選,由padding和4條padding edge組成。若padding寬度設定為0,則padding edge與content edage重疊;
  3. border box:可選,由border和4條border edge組成。若border寬度設定為0,則border edge與padding edage重疊;
  4. margin box:可選,由margin和4條margin/outer edge組成。若margin寬度設定為0,則margin edge與border edage重疊。
  對於剛接觸CSS的同學,經常會將"通過width/height屬性設定div元素的寬/高"掛在口邊,其實這句話是有誤的。
  1. 首先css屬性width和height作用於div元素所產生的盒子,而不是元素本身;
  2. 另外盒子模型由4個盒子組成,那width和height到底是作用於哪些盒子呢。
  這裡就分為IE盒子模型和標準盒子模型了。
   IE box model     
IE5.5(怪異模式)採用IE盒子模型,其它將使用W3C標準盒子模型。

width = content-width + padding-width + border-widthheight = content-height + padding-height + border-height

 
  Standard box model   

width = content-widthheight = content-height


遊走於IE box model 和 Standard box model間的通道——box-sizing屬性
  我們看到存在兩種width/height的劃分方式,到底哪種才對呢。其實兩種都對,具體看如何使用而已。另外IE8開始支援CSS3屬性box-sizing,讓我們可以自由選擇採用哪種盒子:)
  box-sizing:content-box/border-box/inherit
                  content-box——預設值,採用Standard box model
                  border-box——採用IE box model
                  inherit——繼承父元素屬性值
sample:

Element{  -moz-box-sizing: border-box; // FireFox3.5+  -o-box-sizing: border-box; // Opera9.6(Presto核心)  -webkit-box-sizing: border-box; // Safari3.2+  -ms-box-sizing: border-box; // IE8  box-sizing: border-box; // IE9+,Chrome10.0+,Safari5.1+,Opera10.6}


行級盒子——懷疑人生de起點:)                  
  之前我理解的盒子模型如上所述,當我看到行級盒子的種種現象時,便開始懷疑人生了:(
 width/height不起作用。。。

.defined-wh{  width: 100px;  height: 50px;  border: solid 1px red;  background: yellow;}

對於block-level box

<div class="defined-wh"></div>


對於inline-level box

<span class="defined-wh"></span>


  行級盒子的寬度怎麼會是0呢。高度是有的但不是50px啊,到底什麼回事啊。
  原因很簡單,那就是行級盒子的content box的高/寬根本就不是通過height/width來設定的。
  content box/area的高由font-size決定的;
  content box/area的寬等於其子行級盒子的外寬度(margin+border+padding+content width)之和。

  行級盒子被擠斷了。。。

.broken{  border: solid 1px red;  background: yellow;}

對於block-level box

<div class="broken">一段文字一段文字一段文字一段文字一段文字一段文字</div>


對於inline-level box

<span class="broken">一段文字一段文字一段文字一段文字一段文字一段文字</span>


行級盒子被五馬分屍了,可憐兮兮的。更可憐的是我理解不了。。。
其實W3C Recommendation有說明的哦。
>The box model for inline elements in bidirectional context
>When the element's 'direction' property is 'ltr', the left-most generated box of the first line box in which the element appears has the left margin, left border and left padding, and the right-most generated box of the last line box in which the element appears has the right padding, right border and right margin.
>When the element's 'direction' property is 'rtl', the right-most generated box of the first line box in which the element appears has the right padding, right border and right margin, and the left-most generated box of the last line box in which the element appears has the left margin, left border and left padding. 
  就是說當inline-level box寬度大於父容器寬度時會被拆分成多個inline-level box,
當屬性direction為ltr時,margin/border/padding-left將作用於第一個的inline-level box,margin/border/padding-right將作用於最後一個的inline-level box;若屬性direction為rtl時,margin/border/padding-right將作用於第一個的inline-level box,margin/border/padding-left將作用於最後一個的inline-level box。
看到了沒。行級盒子真的會被分屍的,好殘忍哦:|

 行級盒子怎麼不佔空間了。怎麼刷存在感啊。。。

.existed{  margin: 20px;  padding: 20px;  border: solid 1px red;  background: yellow;  background-clip: content-box;}

對於block-level box

<div>before bababababababa</div><div class="existed">babababababababababa</div><div>after bababababababa</div>


對於inline-level box

<div>before bababababababa</div><span class="existed">babababababababababa</span><div>after bababababababa</div>


  看,行級盒子的margin/border/padding-top/bottom怎麼均不佔空間的。難道行級盒子僅有content box占空間嗎。
這裡已經涉及到水平和垂直方向排版的範疇了,僅以盒子模型已無法解析理解上述的問題。
(要結合https://www.w3.org/TR/CSS2/box.html和https://www.w3.org/TR/CSS21/visuren.html、https://www.w3.org/TR/CSS21/visudet.html來理解了。)

在深入解釋inline-level box的上述現象前,我們需要補充一下:
1. 一個元素會對應0~N個box;(當設定`display:none;`時,則對應0個box)
2. 根據`display`屬性值,元素會對應不同類型的controlling box(inline/block-level box均是controlling box的子類). 就CSS2而言`display:inline|inline-block|inline-table|table-cell|table-column-group`的元素對應inline-level box,而`display:block|list-item|table|table-caption|table-header-group|table-row|table-row-group|table-footer-

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.