bfc (收集的)

來源:互聯網
上載者:User

標籤:style   blog   http   io   使用   ar   for   檔案   div   

一些基本概念
  • viewport: 展現網頁的媒體,比如視窗或者某個地區,它的大小是有限制的,為了不被平台術語所束縛,我們給他起名viewport,中文意思就是視口。
  • canvas: 而我們在渲染網頁的時候通常並不知道我們需要多大的空間,而且這些空間通常尺寸會超過viewport的大小,於是實際上我們需要設想一個無限大的畫布來繪製我們的元素,我們把它稱為canvas。
  • box: element(元素)和node(節點)是大家很熟悉的概念,當我們做布局計算的時候,通常會把節點變成box,一個節點可能產生多個box,虛擬元素也會產生box。
  • render tree: 對應於dom樹,我們把box的內含項目關聯性構成的屬性結構成為渲染樹render tree
BFC

首先我們來考慮一個基本的情況:

run

<html>  <head><title>囧</title></head>  <body>    <div style="width:300px;height:50px;"></div>    <div style="width:300px;height:20px;"></div>    <div style="height:50px;"></div>    <div style="width:300px;height:50px;"></div>  </body></html>

之所以簡單是因為這些div每一個只產生一個盒子,預設的display下,div產生塊級盒,為了讓塊級盒按照我們的意願排布,我們需要引入一個概念:block formatting context,簡稱BFC。

BFC其實是個相當簡單的概念,然而因為實在中文中沒啥合適的詞來形容(你不覺得"塊級格式化上下文"比BFC更讓人覺得不知所云嗎?),這個概念已經被傳得極其神秘:

在 CSS 面試中問 BFC 等概念,就如在 JS 面試中問閉包等概念一樣,經常會刷掉一些真正優秀的人。 ——玉伯

甚至很多人連它是動詞還是名詞都搞不清,不信你可以搜尋一下觸發BFC,親,BFC是名詞啊……怎麼它就能觸發呢?

簡單地說,BFC就是像例子裡面一樣順次豎著排塊級盒的一種上下文。豎著排盒子而已,豎著排盒子有什麼理解不了的啊我X?

好吧平複一下情緒,我們繼續說,canvas會設立一個BFC,這也是最外層的formatting context了,問題的複雜性在於有些塊級盒內部也可以產生BFC(至少它必須也能包含塊級盒),於是說BFC是可以嵌套滴:

run

<html>  <head><title>囧</title></head>  <body>    <div style="width:300px;height:100px;">      <div style="width:300px;height:20px;"></div>      <div style="height:50px;"></div>    </div>    <div style="height:50px;"></div>  </body></html>

不是所有塊級盒內部都可以產生BFC,比如說要是這盒裡面連塊級盒都沒有,都是行內盒那就產生IFC:

run

<html>  <head><title>囧</title></head>  <body>    <div style="width:300px;height:100px;overflow:visible;">      <span>囧</span><span>囧囧</span>    </div>    <div style="height:50px;"></div>  </body></html>

不過,只要它的子節點裡面有一個塊級盒,它就產生BFC,那些行內元素,會自動套一個匿名的塊級行盒。

run

<html>  <head><title>囧</title></head>  <body>    <div style="width:300px;height:100px;overflow:visible;">      <span>囧</span><div>啦啦啦</div><span>囧囧</span>    </div>    <div style="height:50px;"></div>  </body></html>

又比如說overflow:visible的塊盒就不產生BFC,不但不產生BFC,啥FC都不產生,它的子項目直接搞進自己外層的BFC鳥:

run

<html>  <head><title>囧</title></head>  <body>    <div style="width:300px;overflow:visible;">      <p style="width:200px;height:20px;"></p>      <p style="height:50px;">aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa</p>    </div>    <p style="height:50px;"></p>  </body></html>

overflow:visible這個限制只對所謂的塊盒(既包含塊級盒、自己又是塊級盒)存在,有些盒內部也能包含區塊層級元素,但是它本身又不是區塊層級元素(比如display為table-cell、inline-block、或者盒本身是flex item等),因為外面不是BFC,所以它們不論如何一定會給包含的塊級盒建立一個新的BFC出來。

同一個BFC裡面的盒還會有margin collapse現象,詳情見此文 《談margin collapsing(外邊距疊加)》

IFC

IFC裡面可能有文字、行內元素混合排布:

run

<html>  <head><title>囧</title></head>  <body>    <div style="">      <span>囧</span>囧囧囧<span>囧囧</span>    </div>  </body></html>

文本的排布是個很複雜的事情,在dom樹中,我們儲存的是字元和字串,而在render tree中,我們要使用一個新的概念:字型(glyph)。字型檔(通常是ttf,ture type格式的)中包含著不同字型下字元到字型的規則。

一個字型有很多屬性,下面這張圖來自freetype,它是大部分瀏覽器使用的文字排版基礎庫:

詳情請看這裡。

圖中的那根加粗的X軸就是傳說中的基準(base line)了,文字預設是按照基準對齊的。

下面這個demo展示了一個IFC中的幾條重要的基準線:

 baseline sub super top text-top middle bottom text-bottom 

  great it works!2囧啊

在水平方向,文字的排布主要受到以下屬性影響

  • word-break, word-spacing, word-wrap
  • letter-spacing
  • white-space
  • text-align
  • hyphenate-character, hyphenate-limit-after, hyphenate-limit-before, hyphenate-limit-lines, hyphens
  • justify-content
  • ……

總之很複雜,講也講不完,而且大家又不要寫瀏覽器所以大家就大概望文生義一下好了(po主被扔蛋中……)。

對於一個正常的"行盒"來說,文字總是垂直置中排布的。

在縱向,文本排布主要受line-height屬性影響,在有行內盒參與的情況下就複雜了,

一個行內盒的vertical-align可以有這樣幾種取值:

  • baseline
  • sub
  • super
  • top
  • text-top
  • middle
  • bottom
  • text-bottom

它也可以是某一指定高度。根據行內盒的對齊,它有可能把這行盒向上或者向下"撐大",造成超過行高的情況。

所以行盒在BFC中佔據的實際高度,很可能大於line-height。

文字的baseline很好理解,而行內元素則比較複雜,特別是當行內元素自身又是容器的時候:

run

<html>  <head><title>囧</title></head>  <body>    <div style="overflow:visible;">      <span>囧</span>囧囧囧<div style="display:inline-block;width:300px;height:300px;"></div><span>囧囧</span>    </div>  </body></html>

run

<html>  <head><title>囧</title></head>  <body>    <div style="overflow:visible;">      <span>囧</span>囧囧囧<div style="display:inline-block;width:300px;height:300px;">123<br/>123<br/>123</div><span>囧囧</span>    </div>  </body></html>
浮動

浮動是個行級的行為,當遇到浮動元素的時候,會首先"假裝"它是個行內元素進行排版,排好後就往浮動的方向擠到擠不過去為止(遇到邊界或者其它浮動元素)。

run

<html>  <head><title>囧</title></head>  <body>    <div style="">      <span>囧</span>囧囧囧<div style="display:inline-block;width:300px;height:300px;float:left"></div><span>囧囧</span>    </div>  </body></html>

run

<html>  <head><title>囧</title></head>  <body>    <div style="">      <span>囧</span>囧囧囧<div style="display:inline-block;width:300px;height:300px;float:left"></div><span>囧囧</span><br/>
<div style="display:inline-block;width:300px;height:300px;float:left"></div> </div> </body></html>

某一方向有clear的時候,浮動元素總是擠到邊界,在垂直方向上的行為類似"換行"。

run

<html>  <head><title>囧</title></head>  <body>    <div style="">      <span>囧</span>囧囧囧<div style="display:inline-block;width:300px;height:300px;float:left"></div><span>囧囧</span><br/><div style="clear:left;display:inline-block;width:300px;height:300px;float:left"></div>    </div>  </body></html>

排好一個浮動元素之後,這一行就要重排一次。所以說浮動元素會造成行級的reflow。重排的時候,行盒會躲開浮動元素。之後的塊級盒(不論是行盒還是其它盒)也都會躲開浮動元素排布。

bfc (收集的)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.