hasLayout與Block formatting contexts的學習(上)

hasLayout與Block formatting contexts的學習

@(css BFC)[IE hasLayout|妙瞳]css

hasLayout是什麼?

haslayout 是Windows Internet Explorer渲染引擎的一個內部組成部分。在InternetExplorer中,一個元素要麼本身對自身的內容進行計算大小和組織,要麼依賴於父元素來計算尺寸和組織內容。爲了調節這兩個不一樣的概念,渲染引擎採用了 hasLayout 的屬性,屬性值能夠爲true或false。當一個元素的 hasLayout屬性值爲true時,咱們說這個元素有一個佈局(layout)。注意:hasLayout屬性是微軟特有的過期屬性,在IE八、IE9中,hasLayout屬性已經被廢棄。下文中的InternetExplorer都是指IE七、IE6及如下版本。

當一個元素有一個佈局時,它負責對本身和可能的子孫元素進行尺寸計算和定位。簡單來講,這意味着這個元素須要花更多的代價來維護自身和裏面的內容,而不是依賴於祖先元素來完成這些工做。所以,一些元素默認會有一個佈局。當咱們說一個元素「擁有layout」或「獲得layout」,或者說一個元素「has layout」 的時候,咱們的意思是指它的微軟專有屬性 hasLayout 被設爲了 true。一個「layout元素」能夠是一個默認就擁有 layout 的元素或者是一個經過設置某些 CSS 屬性獲得 layout的元素。經過 IE Developer Toolbar 能夠查看 IE 下 HTML元素是否擁有haslayout,在 IE Developer Toolbar 下,擁有 haslayout的元素,一般顯示爲「haslayout = -1」。‘Layout’ 在 IE 中能夠經過 hasLayout 屬性來判斷一個元素是否擁有 layout ,如 object.currentStyle.hasLayout 。html

負責組織自身內容的元素將默認有一個佈局,主要包括如下元素(不徹底列表):css3

<html>, <body>
    <table>, <tr>, <th>, <td>
    <img>
    <hr>
    <input>, <button>, <select>, <textarea>, <fieldset>, <legend>
    <iframe>, <embed>, <object>, <applet>
    <marquee>
對於並不是全部的元素都默認有佈局,微軟給出的主要緣由是「性能和簡潔」。若是全部的元素都默認有佈局,會對性能和內存使用上產生有害的影響。http://www.satzansatz.de/cssd/onhavinglayoutrev07-20060517.html

haslayout 問題的調試與解決瀏覽器

當網頁在 IE 中有異常表現時,能夠嘗試激發 haslayout 來看看是否是問題所在。經常使用的方法是給某元素 css 設定 zoom:1。使用 zoom:1 是由於大多數狀況下,它能在不影響現有環境的條件下激發元素的 haslayout。而一旦問題消失,那基本上就能夠判斷是haslayout 的緣由。而後就能夠經過設定相應的 css 屬性來對這個問題進行修正了。建議首先要考慮的是設定元素的width/height 屬性,其次再考慮其餘屬性。
對 IE6 及更早版原本說,經常使用的方法被稱爲霍莉破解(Holly hack),即設定這個元素的高度爲 1%(height:1%;)。須要注意的是,當這個元素的 overflow 屬性被設置爲 visible 時,這個方法就失效了。或者使用 IE的條件註釋。
對 IE7 來講,最好的方法是設置元素的最小高度爲 0 (min-height:0;)。
haslayout 問題引發的常見 bug
IE6 及更低版本的雙空白邊浮動 bug
bug 修復: display:inline;
IE5-6/win 的 3 像素偏移 bug
bug 修復: _height:1%;
IE6 的躲躲貓(peek-a-boo) bug
bug 修復: _height:1%;
IE6/7負margin隱藏Bug:
bug 修復:去掉父元素的hasLayout;或者賦hasLayout給子元素,並添加position:relative;app

如何激發 haslayout?佈局

大部分的 IE 顯示錯誤,均可以經過激發元素的 haslayout 屬性來修正。能夠經過設置 css 尺寸屬性(width/height)等來激發元素的 haslayout,使其「擁有佈局」。以下所示,經過設置如下 css 屬性便可。性能

  • display: inline-block
  • height: (除 auto 外任何值)
  • width: (除 auto 外任何值)
  • float: (left 或 right)
  • position: absolute
  • writing-mode: tb-rl
  • zoom: (除 normal 外任意值)

Internet Explorer 7 還有一些額外的屬性(不徹底列表):學習

  • min-height: (任意值)
  • max-height: (除 none 外任意值)
  • min-width: (任意值)
  • max-width: (除 none 外任意值)
  • overflow: (除 visible 外任意值)
  • overflow-x: (除 visible 外任意值)
  • overflow-y: (除 visible 外任意值)
  • position: fixed
    其中 overflow-x 和 overflow-y 是 css3 盒模型中的屬性,目前還未被瀏覽器普遍支持。
    對於內聯元素(默認即爲內聯的元素,如 span,或 display:inline; 的元素),
    width 和 height 只在 IE5.x 下和 IE6 或更新版本的 quirks 模式下觸發 hasLayout 。而對於IE6,若是瀏覽器運行於標準兼容模式下,內聯元素會忽略 width 或 height 屬性,因此設置 width 或 height不能在此種狀況下令該元素具備 layout。
    zoom 老是能夠觸發 hasLayout,可是在 IE5.0 中不支持。
    具備「layout」 的元素若是同時 display: inline ,那麼它的行爲就和標準中所說的 inline-block很相似了:在段落中和普通文字同樣在水平方向和連續排列,受 vertical-align影響,而且大小能夠根據內容自適應調整。這也能夠解釋爲何單單在 IE/Win 中內聯元素能夠包含塊級元素而少出問題,由於在別的瀏覽器中display: inline 就是內聯,不像 IE/Win 一旦內聯元素擁有 layout 還會變成 inline-block。

Block formatting contexts是什麼?

本文參考W3C CSS 2.1 規範 Visual formatting model
http://www.w3.org/TR/CSS2/
http://www.w3.org/TR/CSS2/visuren.html#inline-level
http://www.w3.org/TR/CSS2/visuren.html#normal-flowui

Box: CSS佈局的基本單位spa

  Box 是 CSS 佈局的對象和基本單位, 直觀點來講,就是一個頁面是由不少個 Box 組成的。元素的類型和 display 屬性,決定了這個 Box 的類型。 不一樣類型的 Box, 會參與不一樣的 Formatting Context(一個決定如何渲染文檔的容器),所以Box內的元素會以不一樣的方式渲染。讓咱們看看有哪些盒子:

block-level box:display 屬性爲 block, list-item, table 的元素,會生成 block-level box。而且參與 block fomatting context;
inline-level box:display 屬性爲 inline, inline-block, inline-table 的元素,會生成 inline-level box。而且參與 inline formatting context;
run-in box: css3 中才有,暫時不講。http://www.w3.org/TR/css3-box/#run-in-boxes

Formatting context

  Formatting context 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。最多見的 Formatting contexts 有 Block fomatting contexts (簡稱BFC)和 Inline formatting contexts(簡稱IFC)。

  CSS2.1 中只有 BFC 和 IFC, CSS3 中還增長了 GFC 和 FFC。
  
BFC 定義

  BFC(Block formatting contexts)直譯爲"塊級格式化上下文"。它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何佈局,而且與這個區域外部絕不相干。
  
BFC佈局規則

  • 內部的Box會在垂直方向,一個接一個地放置。
  • Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
  • 每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。
  • BFC的區域不會與float box重疊。
  • BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。
  • 計算BFC的高度時,浮動元素也參與計算。
  • 在CSS3中,對這個概念作了改動:http://www.w3.org/TR/css3-box/#block-level0
    CSS3中,將BFC 叫作 flow root。

如何觸發BFC?

  • float:(任何值除了none)
  • overflow:(任何值除了visible)
  • display:(table-cell/table-caption/inline-block)
  • position:(任何值除了static/relative)
    注意:咱們有時會用overflow:hidden的方法去清除浮動,就是由於觸發了元素的BFC(IE6 7要聲明zoom爲1,觸發hasLayout)。能夠參考css float浮動詳解

今天總結到這裏,明天繼續下篇。假若有錯誤或不足的地方,歡迎指出,很是感謝!----妙瞳。

相關文章
相關標籤/搜索