在web前端面試的時候常常會被問及IE的hasLayout問題,有些書籍講解的不是很清楚(害死人了),在網絡上收集一些資料,我認爲比較好的有下面兩篇。
在初學css的時候,很鬱悶的發現同樣的代碼在IE裏和其他的瀏覽器裏表現的判若兩人,很是惱火,費解,調整費時費力,後來才知道IE有一個單獨的屬性:layout,這篇文章仔細的分析一下IE layout,以求能更加深入的瞭解一下,參考文章:http://www.satzansatz.de/cssd/onhavinglayout.html#toc,同時還借鑑了不一樣的蚊子的這篇翻譯IE Haslayout詳解,其中沒有翻譯完,我再完整一下: 引言: Internet Explorer 中有很多奇怪的渲染問題可以給他一個”layout”得到解決,John Gallant 和 Holly Bergevin把他歸類爲“dimensional bugs”(尺寸bug或者尺寸臭蟲),意思是可以給對應的元素賦予寬度和高度解決;這給我們帶來了一個問題:爲什麼layout可以改變渲染模式和元素之間的關係? hasLayout定義: layout是IE/WIN裏面的私有概念,它決定了一個元素如何顯示以及約束其包含的內容、如何和其他元素進行相互作用和聯繫、如何響應和傳遞應用程序事件、用戶事件等; layout的特性可以被某些css樣式屬性不可扭轉的觸發,一些html元素本身擁有layout缺省(默認)屬性; Microsoft的開發者們決定一些元素應該獲得一個“屬性”(在面向對象的編程裏),他們用了“hasLayout”屬性,當渲染特性生效時,他的值被設置成true; 當Microsoft的私有屬性hasLayout被設置成true時,我們說這個元素獲得了佈局(layout)或者說這個元素擁有了佈局(layout),佈局元素可以是他們中的任何之一,如果那些元素擁有默認的 layout佈局或者通過設置合適的css屬性使其獲得佈局(layout); 在非佈局元素(non-layout)中,hasLayout不會被觸發,比如說一個沒有設置寬度和高度(沒有尺寸定義)的div,他是所有非佈局元素的祖宗; 給一個默認沒有 layout 的元素賦予 layout 的方法包括設置可觸發 hasLayout = true 的 CSS 屬性。參考默認 layout 元素以及這些屬性列表。沒有辦法設置 hasLayout = false , 除非把一開始那些觸發 hasLayout = true 的 CSS 屬性刪除或重置。 我們遇到的問題: hasLayout問題,影響那些有經驗的設計師和代碼人員,layout有許多不同尋常且難以預料的作用在盒子模型的展示,甚至有時會牽連他們的後代元素; 一個元素有或者沒有“layout”會引發下列問題: 以上所列只是一個摘要和不完整的; Layout 的由來: 不同於標準屬性,也不像某些瀏覽器的私有 CSS 屬性,layout 無法通過某一個 CSS 聲明直接設定 。也就是說沒有”layout屬性”這麼一個東西,元素要麼本身自動擁有 layout,要麼藉助一些 CSS 聲明悄悄地獲得 layout。 下列元素應該是默認具有 layout 的: 下列 CSS 屬性和取值將會讓一個元素獲得 layout: 有關內聯元素: 對於內聯元素(可以是默認即爲內聯的比如 span 元素,也可以是 display: inline 的元素) 具有”layout” 的元素如果同時也 display: inline ,那麼它的行爲就和標準中所說的 inline-block 很類似了:在段落中和普通文字一樣在水平方向和連續排列,受 vertical-align 影響,並且大小可以根據內容自適應調整。這也可以解釋爲什麼單單在 IE/Win 中內聯元素可以包含塊級元素而少出問題,因爲在別的瀏覽器中 display: inline 就是內聯,不像 IE/Win 一旦內聯元素擁有 layout 還會變成 inline-block。 重置HasLayout: 如果沒有其他屬性再添加 hasLayout 的話,重置下列屬性的默認值就會重新設置或破壞Haslayout: 使用者必須小心使用這些重置屬性。 display 屬性的不同:當用”inline-block”設置了 haslayout = true 時,就算在一條獨立的規則中覆蓋這個屬性爲”block”或”inline”,haslayout 這個標誌也不會被重置爲 false。 把 mid-width, mid-height 設爲它們的默認值”0″仍然會賦予 hasLayout,但是 IE 7 卻可以接受一個不合法的屬性”auto”來重置 hasLayout。 hasLayout腳本屬性: 我們已經選擇參考把“hasLayout”屬性作爲一個腳本屬性,以便把他與我們熟悉的CSS屬性區分開來; 並沒有方法可以直接設置或者重置hasLayout屬性; hasLayout屬性可以用來檢查該元素是否有layout,例如它有一個ID=“eid”,然後可以直接在IE5.5地址欄裏敲: javascript: alert(eid.currentStyle.hasLayout) 這樣就可以檢測出它的狀態; IE的Developer Toolbar允許你動態的檢查當前元素的樣式,當hasLayout的值爲“true”時,它的值被呈現爲“-1”,例如,如果你想編輯一個節點的屬性的時候,你可以CSS的“zoom”屬性爲“1”(zoom=1),這樣可以觸發那個hasLayout屬性,以便dubug它; 另一件需要考慮的是:layout怎麼作用和影響腳本(script),例如:那些沒有layout特性的元素的 clientWidth/clientHeight屬性總是返回0,這對於新手來說是難以理解並且是莫名其妙的,並且它和 Mozilla(firefox)瀏覽器的作用有很大出入,我們能利用這個事實來爲IE5.0做決定,就像這樣,如果那個clientWidth是0,那麼我們說這個元素沒有layout; CSS Hacks 在IE7和它以前的版本里,下面的這些hack已經得到了驗證: John Gallant 和 Holly Bergevin在2003年發佈了這個Holly hack: 給IE6以及它以下的版本layout,也可以用這個underscore hack: .gainlayout { _height: 0; } 並且爲了給IE7layout,我們可以用min-hight屬性: .gainlayout { min-height: 0; } 二者選一的,這是比較有效的功能,就是conditional comments: <!–[if lte IE 6]> 在外部樣式表引入之時,插入一條受限制的註釋,是比較簡潔和可靠的解決辦法: <link rel=”stylesheet” href=”allbrowsers.css” type=”text/css” /> <!–[if lte IE 7]> 給IE6及他以下的版本設定高度總是被用到的,除非他和某些特性衝突(overflow:hidden);那些1%,1px或者0基本上都是相等的,但是那個1%有時候會出現一些問題(即使極少碰到); 在標準模式下給元素設定高度是不可用的,在IE7裏應該儘可能避免(或者小心的使用:兩個條件:<1>只能是百分值<2>其父元素必須沒有確定的高度),鑑於這些原因,我們喜歡用:dispaly:inline-block或者zoom:1; 我們已經對那些浮動(float)元素試驗了“holy”hacks,或者那些已經擁有寬度(width)的元素,記住這個目標就是:不能運用這些hacks在擁有height的元素上,因爲這樣會觸發hasLayout=ture; 不要對所有的元素這樣: * {_height: 1px;} 這樣是不合適的,因爲它不僅僅讓擁有layout的沒有變好,反而改變了那些基本元素的渲染和展示; hack管理(management): 儘管IE7已經發布了,但是我們仍然不能預見將來的IE版本是否繼續需要hasLayout來修復bug和他們是怎麼相互作用的,所以用MS的私有屬性zoom或者有田間的條件註釋是明智的: <!–[if lt IE 7]><style> <!–[if IE 7]><style> 如果想得到一個更詳盡的hasLayout觸發和hasLayout在不同的IE版本里的比較的話,請參考這裏:Thoughts on IE hack management. IE Mac簡短介紹: IE Mac和IE for Windows是十分不同的,每一種都有自己的渲染引擎,IE Mac用任何方式都不知道hasLayout的行爲,IE Mac渲染引擎是在向標準遵循模式靠近; 吾IE layout詳解
絕對定位元素的包含區塊(containing block)就會經常在這一方面出問題。
由於 layout 元素的特性,浮動模型會有很多怪異的表現。
當一個內聯級別的元素需要 layout 的時候往往就要用到它,這也可能也是這個 CSS 屬性的唯一效果–讓某個元素擁有 layout。”inline-block行爲”在IE中是可以實現的,但是非常與衆不同: IE/Win: inline-block and hasLayout 。
當遇到layout錯誤的展現效果是,一般都會嘗試設定高度來修復
height: 1% 就在 Holly Hack 中用到。
IE專有屬性。不過 zoom: 1 可以臨時用做調試。
MS專有屬性。
在 IE7 中,overflow 也變成了一個 layout 觸發器,這個屬性在之前版本 IE 中沒有觸發 layout 的功能,除非這個元素被其他情況觸發添加到了一個盒子中;
overflow-x 和 overflow-y 是 CSS3 盒模型中的屬性,尚未得到瀏覽器的廣泛支持。他們在之前版本IE中沒有觸發 layout 的功能。
就算設爲0也可以讓該元素獲得 layout。
即使設爲0也可以讓該元素的 haslayout=true
* html .gainlayout { height: 1%; }
<style>
.gainlayout { height: 1px; }
</style>
<![endif]–>
<link rel=”stylesheet” href=”iefix.css” type=”text/css” />
<![endif]–>
.gainlayout { height: 0; }
</style><![endif]–>
.gainlayout { zoom: 1; }
</style><![endif]–>
IE Layout詳解
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.