標籤:des style blog http tar ext
網路上有很多關於hasLayout和BFC相關的文章,但是大部分都顯得有些晦澀難懂。所以想用一些比較直觀的例子來說明hasLayout和BFC給平時的布局帶來的影響。
基礎知識
在講hasLayout和BFC之前,先簡單地過一下元素布局的一些基本知識。
元素本身的布局方式可以從display上表現出來
- block,對應區塊層級元素
- inline,對應行內元素
- inline-block
- none
當然,還有更多的一些屬性,我們只提及主要部分。
區塊層級元素,在瀏覽器中通常是垂直布局,然後可以用margin來控制區塊層級元素之間的間距,並列和嵌套的區塊層級元素都存在外邊距,也就是margin合并的問題。
而行內元素是以水平的方式布局,垂直方向的margin,padding都是無效的,並且設定的寬高也是無效的。
BFC的全名是block formatting context,轉成中文就是區塊層級元素格式上下文,聽起來有些彆扭,字面上的意思大概就是一個元素的布局上下文類型。
而大家應該對hasLayout已經很熟悉了,更多可能是因為IE5.5/6/7上一些奇怪的bug(還有處於quirks模式下的IE8)。
BFC和hasLayout是作為元素的一種隱藏屬性存在,並且一旦觸發之後就無法復原轉。他們之間有很多共同點。(註:沒有辦法設定hasLayout=false, 除非把一開始那些觸發hasLayout的CSS屬性去除,此處是我沒有表達好,謝謝@貘吃饃香指正)
共同點 1.不和浮動元素重疊
如果一個浮動元素後面跟著一個非浮動的元素,那麼就會產生一個覆蓋的現象,很多自適應的兩欄布局就是這麼做的。
這裡我們使用msdn上的一個例子,來說明haslayout和BFC對這個情況的影響。
<div style="float:left; border: 2px solid red"> 123</div>
<span style="border: 2px solid blue">
The quick brown fox jumped over the lazy dog‘s back.
The quick brown fox jumped over the lazy dog‘s back.
The quick brown fox jumped over the lazy dog‘s back.
The quick brown fox jumped over the lazy dog‘s back.
The quick brown fox jumped over the lazy dog‘s back.
</span>
我們可以看到,文字環繞著浮動元素進行布局。
但是如果我們用overflow:hidden和zoom:1,分別觸發BFC和hasLayout,那麼,結果會是如何呢?
加上觸發條件的代碼如下
<div style="float:left; border: 2px solid red"> 123</div>
<span style="border: 2px solid blue;display:block;overflow:hidden;*zoom:1">
The quick brown fox jumped over the lazy dog‘s back.
The quick brown fox jumped over the lazy dog‘s back.
The quick brown fox jumped over the lazy dog‘s back.
The quick brown fox jumped over the lazy dog‘s back.
The quick brown fox jumped over the lazy dog‘s back.
</span>
結果如,點此查看demo
那麼,實際開發中,這個特性可以用於解決什麼問題呢?
比如百度知道(http://zhidao.baidu.com/)首頁右欄有一個本周知道之星
結構也很簡單,就是
<img/>
<div>
<h4>天涯魔鬼訓練營</h4>
<p>大將軍 十八級</p>
</div>
他給img和div分別加了float:left來解決左右欄排版的問題。
但是,假設(僅僅是假設)描述部分多了幾個字,就變成了這樣
實際情況中不應該存在那麼高的等級,但是至少,我們有辦法提供布局的容錯性。
那麼,如果我們將img設定float,div不設定float,效果就變成了這樣:
我多加了幾個字,顯得有些誇張,很明顯,結果依然不是我們想要的。
我們想要的結果應該是這樣。
怎麼樣才能在文字長度不可控的情況下,保證布局的穩定性呢?
再回到之前講的共同點1,你應該知道怎麼解決這個問題了。
點此查看demo
當然,還有更多應用的情境
例如一個簡單的三欄布局,左右兩欄定寬,中間部分自適應,點此查看demo
2.清除元素內部浮動
點此查看樣本
在樣本中,我們可以看到outer元素在設定overflow:hidden和zoom:1之後,元素內部浮動對外部的影響被清除。也就是我們最常用的清除浮動在IE5.5/6/7上生效的原理。
.k2-fix-float:after{
content:"\0020";
display:block;
height:0;
clear:both;
}
.k2-fix-float{
*zoom:1;
} 3.嵌套元素邊距摺疊問題的解決
點此查看demo
不同點 1.hasLayout的元素被限制為一個矩形
觸發haslayout的元素是可以設定寬高的,而觸發BFC的元素不一定可以設定寬高,比如一個行內元素,設定float或者設定overflow都可以觸發BFC,但是前者可以設定寬高,後者卻不能,但是仔細考慮一下,給一個行內元素設定overflow:hidden還是一見比較扯蛋的事情。
點此查看demo
2.hasLayout的元素設定display:inline後與inline-block行為類似
該特性在IE6/7下解決inline-block問題時也有遇到
.k2-inline-block{
display:-moz-inline-stack;
display:inline-block;
*display:inline;
*zoom:1;
vertical-align:middle;
position:relative;/* 解決因為父容器{display:inline;}問題導致Firefox中li裡面的連結不可點的bug */
_position:static;/* 解決因為IE6中因為上一行代碼帶來在{position:relative}容器中移位在bug */
}
這個狀態下的元素和普通文字一樣在水平方向連續排列,受vertical-align的影響,並且可以按照容器大小自適應調整。
更多補充
BFC和hasLayout在實際開發中還是要分為兩個內容分別看待,特別是haslayout這個屬性,按照現在的狀況,它帶來的困擾還是蠻大的。
hasLayout相關的問題列幾個,更多可以看最後的參考文獻:
1. 浮動元素的寬度自適應問題
2.相對定位元素本身不會觸發hasLayout,但是在重新整理頁面,調整視窗,滾動頁面,選中內容的時候,會出現內容消失或者錯誤,因為IE在設定相對定位元素之後,如果需要做位移處理等等,會忘了告訴其子孫元素進行“重繪”。
3.絕對位置元素如果沒有觸發hasLayout帶來的問題
4.濾鏡是只適用於hasLayout的元素的
參考資料
本文所用到的CSS解決方案來自口碑網K2架構,詳細可以訪問https://github.com/f2e/k2,K2架構改進自YUI3,作為口碑網前端、前後端的解決方案。
- on having layout
- The IE6 Three Pixel Text-Jog
- CSS 101: Block Formatting Contexts
- Everything you Know about Clearfix is Wrong
- Block formating contexts, ‘hasLayout’ – IE Window vs CSS2.1 browsers: simulations
- "HasLayout" Overview
- Visual formatting model