2014年1月26日css
首先,hasLayout 和 Block Formatting Contexts 分別是什麼?html
一、hasLayout是IE內部的一個特有的隱形屬性,屬性值爲true/false。元素一旦擁有了這個屬性,就擁有了佈局,也就是說該元素能夠對本身及其子元素進行尺寸計算和定位(比起依賴父元素進行佈局會花費更大的代價)。因爲這個元素是隱形的,不能經過CSS來設置hasLayout:true/false;能夠經過js來檢測元素是否擁有佈局。hasLayout是隻讀屬性,一旦觸發,不可逆轉。有些元素自己就默認擁有佈局,有的元素能夠經過一些CSS屬性設置(如display、width、height等)來激發產生布局。並非全部元素都擁有佈局的緣由是爲了簡潔和提升性能,擁有佈局會消耗內存,並不輕量,會下降性能。最經常使用的是在CSS中設置zoom:1;來激發佈局,不會產生任何其餘影響的狀況下讓元素擁有佈局。
二、BFC(塊級格式化上下文)就是一種屬性,該屬性會影響着元素的定位和與其兄弟元素之間的相互做用。擁有BFC的元素能夠當作是被隔離了的獨立的容器,容器裏面的元素在佈局上不會影響到容器外面的元素,它是屬於普通流(在CSS 2.1中有三種定位方案:普通流、浮動、絕對定位)的,所以不會對兄弟元素產生影響。
那麼,怎麼觸發hasLayout 和 BFC ?
一、那些元素自己就擁有layout:
- Images
- Tables, TableRows, TableCells
- HR
- Input elements: text, button, file, select
- Marquee
- Framesets, Frames
- Objects, applets, plugins
- Absolute positioned elements
- Floated elements
- Inline-block elements
- Filters (rotation, dropshadow, etc.)
- Body (as well as HTML element in strict mode)
二、哪些元素可以得到layout?
- 在strict mode下,指定width或height的塊級元素。
- 兼容模式下, 指定了widht或height的任何元素
- 設定了zoom屬性的元素
- 可編輯狀態下的元素
- 擁有viewlink行爲的元素
- 元素的Layout-flow屬性跟父元素的不一樣(rtl to ltr)
三、怎麼觸發BFC?
知足下面任一條件的元素,會觸發爲 BFC :
- 浮動元素,float 除 none 之外的值
- 絕對定位元素,position(absolute,fixed)
- display 爲如下其中之一的值 inline-blocks,table-cells,table-captions
- overflow 除了 visible 之外的值(hidden,auto,scroll)
可是,"display:table" 自己並不產生 BFC,而是由它產生匿名框,匿名框中包含 "display:table-cell" 的框會產 BFC。 總之,對於 "display:table" 的元素,產生 BFC 的是匿名框而不是 "display:table"。算法
在 CSS3 中,BFC 叫作 Flow Root,並增長了一些觸發條件:瀏覽器
- display 的 table-caption 值
- position 的 fixed 值,其實 fixed 是 absolute 的一個子類,所以在 CSS2.1 中使用這個值也會觸發 BFC ,只是在 CSS3 中更加明確了這一點。
而後,hasLayout 和 BFC 都有什麼特性呢?
一、hasLayout
- 它會將元素限制在一個矩形的盒子內,從而保證元素的內容不會分散到另外一個盒子周圍,例如,在IE引擎中,一個擁有佈局邊框的元素不會環繞相鄰的浮動元素。這點很重要,在不少地方都用到,例如人人、微博、留言等左邊的頭像用浮動,右邊的內容讓其擁有佈局。
- 因爲Layout使得瀏覽器渲染引擎要額外地在內存中調用算法來計算元素尺寸和方位,因此它並不輕量,它會消耗更多的內存,並可能致使性能的降低。
- 會產生元素沒法自適應大小的反作用,一個擁有Layout的元素不會「自動縮小」來適應其子元素,例如,一個絕對定位具備Layout的盒模型若是有一個擁有Layout的子元素,它是不會自動縮小來適應這個子元素的尺寸的。
- 而一個擁有Layout的盒模型會被子元素給撐開(IE6下的heigh bug)
- 人們一般利用Layout來解決IE6bug,特別是與相對定位元素有關的,但實際上,相對定位元素不須要擁有Layout,若是讓它們擁有Layout在一些狀況下反而會產生問題。
-
若是一個元素擁有了佈局,而且設置display:inline;那麼它實際上跟設置了display:inlin-block;效果同樣。app
二、BFC佈局
(1)、BFC會阻止外邊距摺疊性能
兩個相連的div的垂直方向的外邊距會摺疊,前提是這兩個div在同一塊級格式上下文中(這點有人認爲是CSS的bug,但更好的解釋是把它當作是CSS的一個特性,以前居然一直沒注意到這點==、),要阻止外邊距摺疊,讓父元素建立BFC,這樣其子元素就不會與父元素產生外邊距摺疊的狀況。spa
(2)、BFC能夠包含浮動的元素orm
這個地方主要是閉合浮動的原理。在CSS中設置overflow:hidden/auto;來觸發BFC以防止父元素的高度塌陷。例如 (這裏的元素都沒設置固定高)有一個div的父元素,其子元素浮動佈局,這樣子元素就脫離了文檔流,父元素div就至關於一個空標籤,發生了高度塌陷。利用overflow:hidden/auto;激發BFC,讓其能夠包含浮動元素,閉合浮動。htm
(3)、BFC能夠阻止元素被浮動元素覆蓋
浮動元素的塊級兄弟元素會無視浮動元素的位置,儘可能佔滿一整行,這樣就會被浮動元素覆蓋,爲該兄弟元素觸發 BFC 後能夠阻止這種狀況的發生。值得注意的是,假設浮動元素寬度和它的非浮動兄弟元素寬度都沒有超過父元素寬度,但兩個元素的寬度加起來超出了父元素寬度的時候,非浮動元素會降低到下一行,即處於浮動元素下方。
hasLayout 和 BFC ?
其實hasLayout 和 BFC 的功能是類似的,只是hasLayout是用來處理IE bug的,因此在實際的開發過程當中,爲了兼容各個瀏覽器,在代碼方面,.bj {zoom:1;overflow:hidden;}這部分可寫到css的公共文件中,哪一個地方用到了就添加此class。
上述部份內容參考:http://kayosite.com/block-formatting-contexts-in-detail.html
http://www.cnblogs.com/yilian/