什麼是hasLayout?hasLayout 是IE特有的一個屬性。很多的ie下的css bug都與其息息相關。在ie中,一個元素要麼自己對自身的內容進行計算大小和組織,要麼依賴於父元素來計算尺寸和組織內容。當一個元素的 hasLayout屬性值為true時,它負責對自己和可能的子孫元素進行尺寸計算和定位。雖然這意味著這個元素需要花更多的代價來維護自身和裡面的內 容,而不是依賴於祖先元素來完成這些工作。
下列元素預設 hasLayout=true
<table> <td> <body> <img> <hr> <input> <select> <textarea> <button> <iframe> <embed> <object> <applet> <marquee>
很多情況下,我們把 hasLayout的狀態改成true 就可以解決很大部分ie下顯示的bug。
hasLayout屬性不能直接設定,你只能通過設定一些特定的css屬性來觸發並改變 hasLayout 狀態。下面列出可以觸發hasLayout的一些CSS屬性值。
-------------------------------------
display
啟動haslayout的值:inline-block
取消hasLayout的值:其他值
--------------------------------------
width/height
啟動hasLayout的值:除了auto以外的值
取消hasLayout的值:auto
---------------------------------------
position
啟動hasLayout的值:absolute
取消hasLayout的值:static
----------------------------------------
float
啟動hasLayout的值:left或right
取消hasLayout的值:none
---------------------------------------
zoom
啟動hasLayout的值:有值
取消hasLayout的值:narmal或者空值
(zoom是微軟IE專有屬性,可以觸發hasLayout但不會影響頁面的顯示效果。zoom: 1常用來除錯,不過 ie 5 對這個屬性不支援。)
----------------------------------------
writing-mode: tb-rl
這也是微軟專有的屬性。
ie7還有一些額外的屬性可以觸發該屬性(不完全列表):
min-height: (任何值)
max-height: (任何值除了none)
min-width: (任何值)
max-width: (任何值除了none)
overflow: (任何值除了visible)
overflow-x: (任何值除了visible)
overflow-y: (任何值除了visible)5
position: fixed
因元素hasLayout而導致的問題其實一般都很容易發現:往往是內容出現錯位甚至完全不可見。舉一個典型例子,當一個元素內含浮動或絕對位置的內容時,它通常會表現出奇怪和錯誤的行為,看下面的代碼:
<div id="nofloatbox">
<div id="floatbox"></div>
</div>
CSS代碼如下:
#nofloatbox {
border: 1px solid #FF0000;
background: #CCC;
}
#floatbox {
float: left;
width: 100px;
height: 100px;
border: 1px solid #0000FF;
background: #00FF00;
}
ie顯示結果如:
可見無浮動的div並沒有被裡面的浮動元素的高度撐開,其高度並不會自動計算。我們下面再給這個無浮動的div加上個zoom:1;來觸發其hasLayout屬性試試,css代碼如下:
#nofloatbox {
border: 1px solid #FF0000;
background: #CCC;
zoom:1;
}
#floatbox {
float: left;
width: 100px;
height: 100px;
border: 1px solid #0000FF;
background: #00FF00;
}
儲存重新整理ie瀏覽器視窗,如:
可見這次外圍容器的高度被撐起來了。
同樣,設定上文所述的其他會觸發hasLayout的css屬性都會得到這個結果。
通常firefox等標準的遵守瀏覽器可以加上overflow: hidden;來解決,而IE則不行,需要觸發其hasLayout屬性才可以。
hasLayout對於內嵌元素也可以有效果,當內嵌元素的hasLayout為true的時候,可以給這個內嵌元素設定高度和寬度並得到期望的效果。如下例:
代碼:
<p>今天的<span style="width: 100px; height: 50px; background: #DDD;">天氣</span>真好</p>
效果如所示:
下面給span加上zoom: 1;來觸發hasLayout:
<p>今天的<span style="width: 100px; height: 50px; background: #DDD; zoom: 1;">天氣</span>真好</p>
這回的效果如所示:
要注意的是,hasLayout是微軟專有的東西,對firefox等比較遵守標準的瀏覽器就無效了,因此不可太過依賴。貌似現在的IE8就已經不用特意去觸發hasLayout就可以得到和firefox一致的效果,不知ie8是否已經棄用這個屬性了?
其實依據合理的語義化,恰當的文檔流,正確的標準化所生產出來的頁面,在各個公司出品的標準渲染的瀏覽器下,一般並不會存在太多相容性的問題的。
一 般如果是因為layout而引起的顯示不符期望效果的話,在ff下會表現正常,而在ie下會出現錯誤。這個時候可以嘗試觸發父容器及其中的子容器的 haslayout屬性,通常可以通過加上zoom: 1;來調試。直到找到了產生問題的元素,再進行針對性的修正。最好的辦法是對這個元素設定尺寸屬性。但是,有時不便指定尺寸屬性的情況下,就只能尋找替代 方案了。對於ie7 ,最好的辦法是設定最小高度屬性為0;這個技術是無害的,因為0本來就是這個屬性的初始值。而且沒有必要對其他瀏覽器隱藏這個屬性。而對於ie6和更早版 本中觸發一個元素hasLayout的方法是在overflow屬性是visible的情況下設定這個元素的高度屬性為1%,然後對其他瀏覽器隱藏這個設 置。這種技術就是著名的Holly hack。