php斯芬克斯,斯芬克斯之迷——ie私有属性haslayout的困扰
就象神話中的斯芬克斯一樣,ie的私有屬性haslayout是個神秘且讓人困惑的難纏東西,她只游蕩于ie(這片沙漠)之下。
她無法使用css聲明直接創建。即便是對于ie,她也不能說是一個實實在在存在的屬性。
ie下的元素有些本身擁有haslayout(基本上是一些擁有內在尺寸的可置換元素),有些可以通過一些css屬性可以觸發產生。我們可以在ie developer toolbar上查看到到haslayout這個屬性項,他的值是-1。這說明這個元素觸發了layout。
詳細haslayout資料:On having layout抄錄
更詳細資料:譯文On having layout這篇文章本人還沒怎么看,相信很多問題在這里都有解釋
遇到斯芬克斯是件很麻煩的事情,她會給你提出很多怪怪的讓人困惑的問題,更何況只要我們在ie沙漠中游蕩的話,遇到的概率是非常高的。
遇到她,我們會有三種結果:
猜不出迷題的答案——我們會在迷失在困惑中;
猜錯了迷題的答案——我們會誤會很多東西;
猜對了迷題的答案——恭喜你,你就不用怕斯芬克斯這個丑婆娘了。
那讓我們來猜一下她的幾個比較困惑的問題吧。
斯芬克斯之迷1:是firefox錯了?
*{padding:0;margin:0;}
.wrap{}
#left{float:left;color:red;}
#right{background:#ccc;margin-top:50px;}
left 在FF下,對right設置margin-top。結果不止right上方空出了50px;連left也一樣空出了50px;是FF的解析有問題嗎?left是浮動元素,她脫離了文檔流(注意,這是下一個斯芬克斯之迷),所以right的margin-top相對的是其上級wrap作用的。但我們只是對right設置margin-top。結果在FF下,怎么連left也“產生了margin-top”呢。對比ie和FF下的效果,是不是覺得IE下的解析會比較合理呢?
但是
別忘了影響margin-top/bottom的一個重要規則——margin塌陷(margin collapsing)。
在ff下就是產生了這么一個margin塌陷。導致wrap的”剝奪”了本屬于子元素#right的margin-top值。
為了更加直觀看出是否塌陷,可以給wrap添加一個背景:background:#000;
*{padding:0;margin:0;}
.wrap{background:#000}
#left{float:left;color:red;}
#right{background:#ccc;margin-top:50px;}
left 在FF下,對right設置margin-top。結果不止right上方空出了50px;連left也一樣空出了50px;是FF的解析有問題嗎?在ff下wrap塊的高度并沒有被子元素right的margin-top撐開。反而自身擁有了50px的margin-top。
而浮動的left盡管脫離了文檔流,但還是受其父級限制的(這跟absolute定位的元素層受限于其定義為relative的父級一樣)。所以left還是包含在wrap之中,這樣在ff下看起來left也擁有margin-top,而事實上是因為wrap高度不撐開的結果。
這么說,FF并沒有錯咯,那么IE下又是怎么避開margin塌陷的呢?
問題就出在浮動上面,在ie下,元素浮動將觸發其haslayout。就是這個原因,使得在ie下意外(意外?)的就避開了margin塌陷。
haslayout差點讓我們懷疑了我們的親密伙伴firefox。
———-謎題之外———–
但是,margin塌陷往往不是我們想要的效果。那么我們需要怎么避開他呢?
可以看下這篇獨立文章:如何解決麻煩的margin塌陷(margin collapsing)
斯芬克斯之迷2:在ie下,float元素不脫離文檔流?
在前面的問題里,我們提到浮動元素時一直認為浮動元素脫離文檔流。但是看一下下面這個現象:
ie下,float不脫離文檔流?*{padding:0;margin:0;}
.wrap{}
#left{float:left;color:red;}
#right{background:#ccc;width:500px;}
left ie下width:500px;觸發了#right的layout,所以貌似ie下float并不會脫離文檔流,很多人都一直懷疑浮動元素脫離文檔流的這種說法,就是因為ie下haslayout的經常出現。ie下,浮動的元素(left)牢牢的占著自己的位置。后面的block元素(right),只能跟隨其后(請對比FF下的效果)。
沒錯,這又是haslayout在迷惑我們,這回除了left因為浮動觸發了haslayout外,right也由于使用了width:500px也觸發了haslayout,使得他考慮到了前面浮動的left元素。
如果把right的寬度去掉,或則把值改成auto。就能使ie下達到ff下一樣的效果:后面的block元素會忽略前面浮動元素的存在,直接跑到浮動元素的z軸方向的下面(為什么是下面?因為浮動元素的Z值較正常的要高),而inline元素則環繞此浮動元素。
我們再看一個更加明了的demo:
haslayout影響浮動元素脫離文檔流ie下。去除父級wrap的width:100%。對比效果。由于父級使用width:100%.觸發了haslayout。使得原本脫離文檔流的浮動元素,又在其父級之內擁有了一席之地。
——-謎題之外——–
浮動有三個作用效果:
一是使得自身脫離文檔流,使得父層不適應其高度,而后面的block元素也將忽略其“存在”,跑到浮動元素之下(可在block元素上加背景色查看);
二是使得后面的inline元素“順流環繞”浮動元素。
三是浮動元素的尺寸,如果未定義的話,將按內部元素的尺寸來決定(而不是block元素默認的充滿整行)。而且即便浮動元素本身是非可置換inline元素,她都可以定義width/height(還有margin也將算入尺寸計算)。
其實第一個效果往往不是我們所想要的。所以ie下的haslayout可以說正中我們下懷。那么FF下怎么讓left元素不脫離文檔流(看起來沒有脫離)呢?
在上面的例子中,我們可以對right也使用浮動,或則在right加上overflow:hidden。
知道了這個原理,我們對于這個【右列寬度自適應】的布局(其實這是個左右布局均自適應的布局。一般來說我們會固定左列的寬度)就能很好理解了:
zoom:1針對IE系列觸發haslayout.overflow:hidden針對FF。使得right不會忽視已經脫離文檔流的浮動元素left。
二列,右列自適應寬度布局*{padding:0;margin:0;}
.wrap{overflow:hidden;}
#left{float:left;color:red;}
#right{background:#ccc;zoom:1;overflow:hidden;}
left 更多右列寬度自適應布局的方法:http://www.cssass.com/blog/index.php/2008/31.htmlIE下的haslayout會引發很多問題:
IE 很多常見的浮動 bug 。
元素本身對一些基本屬性的異常處理問題。
容器和其子孫之間的邊距重疊(margin collapsing)問題。
使用列表時遇到的諸多問題。
背景圖像的定位偏差問題。
使用腳本時遇到的瀏覽器之間處理不一致的問題。
她經常讓我們困惑不堪。
但是只要逐步認識她,重視她。經常懷疑,懷疑自己的懷疑。我們就能慢慢摸清她的謎題,了解問題的本質。
這篇文章發布于 2009年03月21號,星期六,07:02,歸類于 CSS2, 瀏覽器與兼容。您可以跟蹤這篇文章的評論通過 RSS 2.0 feed。
您可以留下評論,或者從您的站點trackback。
總結
以上是生活随笔為你收集整理的php斯芬克斯,斯芬克斯之迷——ie私有属性haslayout的困扰的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文档中的横线怎么打出来(word文档中的
- 下一篇: php在数据库中上传图片格式,如何上传图