CSS

CSS BFC和Float

2017-01-14  本文已影响26人  蛋頭熊

實在是在面試中,倒了太多次CSS的栽,所以透過這次自己的筆記來重新學習一下CSS的基本原理。
這篇文章回講到基礎以及自己解釋的BFC(Block formating context),另外提出float跟bfc之間的互動。最後放上一個在面試遇到的問題,並提供自己的解法。

BFC(Block formating context)

來個MDN上面的基本解釋 : 塊格式化上下文(block formatting context) 是頁面 CSS 視覺渲染(visual CSS rendering)這個過程中的一個概念。它是決定塊盒子的佈局及浮動元素相互影響的一個因素。
下列情況將創建一個塊格式化上下文:

  1. 根元素或其它包含它的元素
  2. 浮動 (元素的 float 不為 none)
  3. 絕對定位元素 (元素的 position 為 absolute 或 fixed)
  4. 行內塊 inline-blocks (元素的 display: inline-block)
  5. 表格單元格 (元素的 display: table-cell,HTML表格單元格默認屬性)
  6. 表格標題 (元素的 display: table-caption, HTML表格標題默認屬性)
  7. overflow 的值不為 visible的元素
  8. 彈性盒子 flex boxes (元素的 display: flex 或 inline-flex)

或許很難記,大概常用的就是float、position:absolute/ fixed、display:inline-block、overflow: 不為visible。
當然這樣講完BFC是怎麼運作還是很茫然,依據葵中劍大大的文中所說[https://swordair.com/css-positioning-schemes-normal-flow/] ,BFC就是在展示元素時,提供一個新的容器包覆著這個元素以及其子元素。而這個BFC對容器內的布局,以及對外的互動有它的規則。
來舉個範例

<body>
<div >
  <div style="background-color:green; float:right; width:100px; margin: 5px 0 0 0 ;">b</div>
  <div style="background-color:red;">a</div>
</div>
</body>
圖1

發現b跳脫文件普通流,但是卻不影響div a的寬度。如果這時候,你將div a的overflow設定成auto,div a 就會產生新的BFC,而BFC的特性就會出現,兩個不同的BFC,邊框會分離。原本div b 的外邊框會緊黏著root(最原始的根元素也會產生BFC唷!)的BFC的邊框,現在出現新的BFC在同一層級,他就只能黏著這新來的BFC的邊框。

<div >
  <div style="background-color:green; float:right; width:100px; margin: 5px 0 0 0 ;">b</div>
  <div style="background-color:red; overflow:auto;">a</div>
</div>
圖2

Float與BFC的巧妙關係

時常子元素設定成Float以後,父元素因為子元素float跳脫普通流,而沒有內容,所以高度變為0。以往最常見的做法就是,多設一個div並設定clear:both,來清除float產生的作用。但其實BFC本身是可以包容float的(這也解釋為什麼float沒有讓整個頁面變成0,因為root有建立一個BFC,以及float可以包住float的故事)
下面就是用overflow來建立BFC來解釋這個特性。

首先,先來看最原始的狀態,子元素設定float,讓父元素的高度變成0。

<body>
<div style="background-color:red;">
  <div style="background-color:green; float:right; width:100px; margin: 5px 0 0 0 ;">b</div>
</div>
</body>
圖3

這時候,其實只要設定overflow,來讓他建立時,同時建立出BFC,就可以讓他包住這個float。

<body>
<div style="background-color:red; overflow:auto;">
  <div style="background-color:green; float:right; width:100px; margin: 5px 0 0 0 ;">b</div>
</div>
</body>
圖4

慘痛的面試題目

這是一個我實際遇到的面試題目,其實很簡單,但我當時菜菜的,就是回答不出來。
題目: 請敘述如何實作一個三欄的頁面,最左跟最右欄要緊貼著邊框,固定大小(如100px),而中間那一欄則依據頁面大小,自適應的變動框度。

大家想一想吧XD

我把我的解法放下面,解法千百種,可以自己解解看。
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />

<body>
  <div style="background-color:green; float:left; width:100px;">left</div>
  <div style="background-color:green; float:right; width:100px;">right</div>
  <div style="background-color:red; overflow:auto;">middle</div>
</body>
上一篇下一篇

猜你喜欢

热点阅读