寂寞的hasLayout
寂寞的hasLayout
hasLayout 是IE特有的一個(gè)屬性,它很寂寞,正因?yàn)榧拍愿愠龊芏嗄涿畹氖虑?#xff0c;很多的ie下的css bug都與其息息相關(guān)。查讀了很多網(wǎng)上關(guān)于haslayout相關(guān)的文章,其中“haslayout-Sinab-搜狐博客”,鏈接地址:http://sinab365.blog.sohu.com/107239414.html這里的文章概括的比較全面,以及涉及的知識(shí)也比較豐富。
zoom: 1; 可以讓 IE5.5+ 的任何元素(包括內(nèi)聯(lián)元素)獲得 layout,但是在 IE5.0 中無(wú)效。
沒(méi)有其他附帶效果(內(nèi)聯(lián)元素會(huì)變成 inline-block,這個(gè)當(dāng)然)。
如果需要通過(guò)驗(yàn)證,應(yīng)該用條件注釋將 zoom 隱藏起來(lái)。
其實(shí)當(dāng)我們考慮到“向后兼容”時(shí)是很自相矛盾的,我們強(qiáng)烈建議頁(yè)面設(shè)計(jì)者回過(guò)頭看一下自己頁(yè)面中用的到的明顯的或是不明顯的“hacks”,并用條件注釋針對(duì)不同瀏覽器重新處理以保萬(wàn)無(wú)一失。
關(guān)于IE Mac 的小問(wèn)題
IE Mac 和 windows 下的 IE 是完全不同的兩個(gè)東西,它們各自擁有自己的渲染引擎,IE Mac 就全然不知“hasLayout”(或contenteditable)所謂何物。相比之下 IE Mac 的渲染引擎要更標(biāo)準(zhǔn)兼容一點(diǎn),比如 height 就是被當(dāng)作 height 處理,沒(méi)有別的效果。因此針對(duì)“hasLayout”的 hacks 和別的解決方法(特別是通過(guò)使用 height 或 width 屬性的)往往對(duì) IE Mac 來(lái)說(shuō)是有害的,所以需要對(duì)其隱藏。更多的關(guān)于 IE Mac 相關(guān)的問(wèn)題可以在 IE Mac, bugs and oddities pages http://www.l-c-n.com/IE5tests/找到。
MSDN 文檔
MSDN 中涉及到 hasLayout 這個(gè) MS 屬性的地方寥寥無(wú)幾,而具體解釋 layout 和 IE 渲染模型之間關(guān)系的則少之又少。
在IE4的時(shí)候,除了未經(jīng)絕對(duì)定位也未指定寬高的內(nèi)聯(lián)元素,幾乎所有元素都有某種 layout(MSDN)。http://msdn.microsoft.com/worksh ... mentandlocation.asp在這種早期的layout概念中,像 border, margin, padding 這些屬性被稱作“l(fā)ayout屬性”,它們是不能應(yīng)用到一個(gè)簡(jiǎn)單的內(nèi)聯(lián)元素上的。換句話說(shuō),“擁有l(wèi)ayout”就可以粗略理解成:“可以擁有這幾個(gè)屬性”。
MSDN 上仍然使用 layout 屬性這種說(shuō)法, 只是含義變了,它們和擁有 layout 的元素已經(jīng)沒(méi)有什么關(guān)系了。在 IE5.5 中方才引入了 MS 的這個(gè)專有屬性 hasLayout,http://msdn.microsoft.com/worksh ... rties/haslayout.asp也只是某種內(nèi)部的標(biāo)志位而已。
在 IE5.5 中,MSHTML Editing Platform(即可以通過(guò)設(shè)置來(lái)允許用戶實(shí)時(shí)編輯、拖動(dòng) layout 元素以及調(diào)整其尺寸等)的文檔中描述了三個(gè)和 layout 相關(guān)的重要特性:
如果一個(gè) layout 元素中有內(nèi)容,內(nèi)容的排版布局將由它的邊界矩形框決定。
擁有 layout 的意思基本上就是表示某元素是一個(gè)矩形。
從內(nèi)部來(lái)說(shuō),擁有 layout 意思就是一個(gè)元素將自己負(fù)責(zé)繪制其內(nèi)部?jī)?nèi)容。
(Editing Platform) http://msdn.microsoft.com/librar ... mshtmleditplatf.asp
和 layout 自身相關(guān)的內(nèi)部工作機(jī)制直到2005年8月才有相應(yīng)文檔描述,當(dāng)時(shí)由于 The Web Standards Project http://www.webstandards.org/和微軟的特別工作小組的原因,Markus Mielke [MSFT] 打開(kāi)了深入討論的大門:
一般來(lái)說(shuō),在 Internet Explorer 的 DHTML 引擎中,元素是不對(duì)自己的位置安排負(fù)責(zé)的。雖然一個(gè) div 或者一個(gè) p 元素都在源碼中有一個(gè)位置,在文檔流有一個(gè)位置,但是它們的內(nèi)容卻是由它們最近的一個(gè) layout 祖先(經(jīng)常是 body)控制安排的。這些元素依賴它們祖先的 layout 來(lái)為他們處理諸如決定大小尺寸和測(cè)量信息等諸多繁重的工作。
(HasLayout概述)http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/cols/dnexpie/expie20050831.asp
分析
我們的分析試圖解釋在已知案例下發(fā)生了什么事情,這種分析也應(yīng)該可以作為未知案例下的指導(dǎo)。但我們這種試圖利用種種測(cè)試案例投石探路的黑箱測(cè)試方法,是注定無(wú)法消除黑箱的神秘感的——我們無(wú)法回答“為什么”的問(wèn)題。我們只能去嘗試了解整個(gè)“hasLayout”模式的工作框架,以及它會(huì)怎樣影響網(wǎng)頁(yè)文檔的渲染。因此,最終我們只能提供一些指導(dǎo)方針(而且只能是指導(dǎo)方針,而不是絕對(duì)的解決方案)。
我們認(rèn)為他們所指的是一個(gè)小窗體。一個(gè) layout 元素的內(nèi)部?jī)?nèi)容是完全獨(dú)立的,而且也無(wú)法影響其邊界外的任何內(nèi)容。
而 MS 屬性 layout 只是某種標(biāo)志位:一旦它被設(shè)定,這個(gè)元素就會(huì)擁有 layout“特性”,這包括體現(xiàn)在其自身以及其非 layout 孩子元素身上的特殊性能——比如浮動(dòng)和層疊等。
這種獨(dú)立性也許正可以解釋為什么 layout 元素通常比較穩(wěn)定,而且它們可以讓某些 bug 消失。這種情況的代價(jià)有二,一是偏離了標(biāo)準(zhǔn),二是它沒(méi)有考慮到今后可能因此出現(xiàn)的 bug 和問(wèn)題。
MS 的“頁(yè)面”模式,從符號(hào)學(xué)角度考慮,可以看做是由很多互不相關(guān)的小的區(qū)塊構(gòu)成,而 HTML 和 W3C 的模式則認(rèn)為“頁(yè)面”模式應(yīng)該是敘述完備的,故事性的相關(guān)信息區(qū)塊構(gòu)成的。
各種情況的詳細(xì)說(shuō)明
清除浮動(dòng)和自動(dòng)擴(kuò)展適應(yīng)高度
浮動(dòng)元素會(huì)被 layou 元素自動(dòng)包含。這是很多新手經(jīng)常遇到的問(wèn)題:在 IE 下完成的頁(yè)面到了標(biāo)準(zhǔn)兼容瀏覽器下所有未清除的浮動(dòng)元素都伸出了其包含容器之外。
Containing Floats http://www.complexspiral.com/publications/containing-floats
how to clear floats without structural markup http://positioniseverything.net/easyclearing.html
相反的情況:如果確實(shí)需要一個(gè)浮動(dòng)元素伸出其包含容器,也就是自動(dòng)包含不是想要的效果時(shí),該怎么辦?你很可能也會(huì)遇到這種頭疼的問(wèn)題,下面的深入討論就是一個(gè)例子:
acidic float tests http://www.satzansatz.de/cssd/acidicfloat.html
在IE中,一個(gè)浮動(dòng)元素總是“隸屬于”它的 layout 包含容器。而后面的元素會(huì)受這個(gè) layout 包含容器影響而不是這個(gè)浮動(dòng)元素影響。
這個(gè)特性和IE6的那個(gè)自動(dòng)擴(kuò)展以適應(yīng)內(nèi)部?jī)?nèi)容寬度的特性,都可以看成是受這個(gè)規(guī)則影響的:“由它的邊界矩形框決定”。
更糟的問(wèn)題:clear 無(wú)法影響其 layout 包含容器之外的 float 元素。如果依賴這個(gè) bug 在 IE 中布局的頁(yè)面要轉(zhuǎn)到標(biāo)準(zhǔn)兼容瀏覽器中,只有全部重做。
IE 的自動(dòng)包含浮動(dòng)元素也是經(jīng)常需要的效果,它在其他瀏覽器中也可以達(dá)到:參考我們的 “和 CSS 規(guī)范類似的地方” 這一部分來(lái)了解一下包含浮動(dòng)元素的相關(guān)內(nèi)容。
浮動(dòng)元素旁邊的元素
當(dāng)一個(gè)塊級(jí)元素緊跟在一個(gè)左浮動(dòng)元素之后時(shí),它應(yīng)該——作為一個(gè)塊級(jí)元素——忽略這個(gè)浮動(dòng)元素,而它的內(nèi)容則應(yīng)該因這個(gè)浮動(dòng)元素而移位:一個(gè)緊跟在左浮動(dòng)元素后的塊級(jí)元素內(nèi)的文字內(nèi)容,應(yīng)該沿著浮動(dòng)元素的右邊順序排列并會(huì)(如果它的長(zhǎng)度超過(guò)浮動(dòng)元素)繼續(xù)排列到浮動(dòng)元素下方。但是如果這個(gè)塊級(jí)元素有 layout,比如由于某種原因被設(shè)置了寬度,那么這整個(gè)元素則會(huì)因浮動(dòng)元素而移位,就好像它自己也是一個(gè)浮動(dòng)元素一樣,因此其中的文字就不再環(huán)繞這個(gè)左浮動(dòng)元素了(而會(huì)形成一個(gè)矩形區(qū)域,保持在它的右邊。)
在 IE5 中一個(gè)塊級(jí)元素的百分比寬度是基于浮動(dòng)元素旁邊的剩余空間計(jì)算的,而在 IE6 中則是依照整個(gè)父塊級(jí)元素的可用空間計(jì)算的。所以在 IE6 中設(shè)置 width: 100% 會(huì)導(dǎo)致某種浮動(dòng)元素旁邊的溢出現(xiàn)象,于是各種布局問(wèn)題也會(huì)因此而來(lái)。
一些關(guān)于浮動(dòng)塊旁邊的 hasLayout 塊的測(cè)試案例:
by using width http://dev.l-c-n.com/IEW2-bugs/float-layout.php
by using min-width (IE 7) and zoom (IE 6) http://dev.l-c-n.com/IEW2-bugs/float-adjecant.php
與此類似,和浮動(dòng)元素相鄰的相對(duì)定位元素,它的位置偏移量應(yīng)該參照的是父元素的補(bǔ)白(padding)邊緣(例如,left: 0; 應(yīng)該將一個(gè)相對(duì)定位元素疊放于它前面的浮動(dòng)元素之上)。在 IE6 中,偏移量 left: value; 是從浮動(dòng)元素的右邊距(margin)邊緣開(kāi)始算起的,這會(huì)因浮動(dòng)元素所占的寬度變化導(dǎo)致水平方向的錯(cuò)位(一個(gè)解決方法是用 margin-left 代替,但是也要注意如使用百分值時(shí)會(huì)有一些怪異問(wèn)題)。
layout blocks with relative positioning adjacent to floated blocks http://dev.l-c-n.com/IEW2-bugs/float-layout2-rp.php
根據(jù)規(guī)范所述,浮動(dòng)元素應(yīng)該與其后的盒子交織在一起。而對(duì)于沒(méi)有交叉的二維空間中的矩形而言這是無(wú)法實(shí)現(xiàn)的。
如果誰(shuí)真的需要向 IE 的這種不當(dāng)行為屈服,那么如何讓標(biāo)準(zhǔn)兼容瀏覽器中的盒子也有類似行為——即類似于 layout 盒子會(huì)自動(dòng)“收縮”而給其前置的浮動(dòng)元素讓出空間的行為——就是一個(gè)問(wèn)題了。我們給出的方法是跟著一個(gè)浮動(dòng)元素創(chuàng)建一個(gè)新的塊級(jí)格式化范圍(block formatting context),這在我們的“和 CSS 規(guī)范類似的地方” 有討論。
可以(再次)訪問(wèn)下面這個(gè)頁(yè)面:
three pixel text-jog http://positioniseverything.net/explorer/threepxtest.html
我們可以看到跟在一個(gè)浮動(dòng)元素后的 layout 元素不會(huì)顯示這個(gè)3px間隙的 bug,因?yàn)楦?dòng)元素外圍的3px硬邊無(wú)法影響一個(gè) layout 元素的內(nèi)部?jī)?nèi)容,所以這個(gè)硬邊將整個(gè) layout 元素右推了3px。好比一個(gè)防護(hù)罩,layout 可以保護(hù)其內(nèi)部?jī)?nèi)容不受影響,但是浮動(dòng)元素的力量卻將整個(gè)防護(hù)罩推了開(kāi)來(lái)。
列表
無(wú)論是列表本身(ol, ul) 還是單個(gè)的列表元素(li),擁有 layout 后都會(huì)影響列表的表現(xiàn)。不同版本 IE 的表現(xiàn)又有不同。最明顯的效果就體現(xiàn)在列表符號(hào)上(如果你的列表自定義了列表符號(hào)則不會(huì)受這個(gè)問(wèn)題影響)。這些符號(hào)很可能是通過(guò)某種內(nèi)部機(jī)制附到列表元素上的(通常是附著在它們外面)。不幸的是,由于是通過(guò)“內(nèi)部機(jī)制”添加的,我們無(wú)法訪問(wèn)它們也無(wú)法修正它們的錯(cuò)誤表現(xiàn)。
最明顯的效果有:
列表獲得 layout 后,列表符號(hào)會(huì)消失或者被放置在不同的或者錯(cuò)誤的位置。
有時(shí)它們又可以通過(guò)改變列表元素的邊距而重新出現(xiàn)。這看起來(lái)似乎是以下事實(shí)導(dǎo)致的結(jié)果:layout 元素會(huì)試圖裁掉超出其邊界的內(nèi)部?jī)?nèi)容。
列表元素獲得 layout 之后,會(huì)有和上面一樣的問(wèn)題出現(xiàn),更多參考 (extra vertical space between list items)http://www.brunildo.org/test/IEWlispace.php
進(jìn)一步又有一個(gè)問(wèn)題就是(在有序列表中)任何具有 layout 的列表元素似乎都有自己獨(dú)立的計(jì)數(shù)器。比如我們有一個(gè)含五個(gè)列表元素的有序列表,只有第三個(gè)列表元素有 layout。我們會(huì)看到這樣:
1… 2… 1… 4… 5…
此外,如果一個(gè)有 layout 的列表元素跨行顯示時(shí),列表符號(hào)會(huì)底部對(duì)齊(而不是按照預(yù)料的頂部對(duì)齊)。
以上某些問(wèn)題還是無(wú)法解決的,所以如果需要列表符號(hào)的時(shí)候最好避免讓列表和列表元素獲得 layout。如果需要限定尺寸,最好給別的元素設(shè)定尺寸,比如給整個(gè)列表外面套一個(gè)元素并設(shè)定它的寬度,又或者比如給每個(gè)列表元素中的內(nèi)容設(shè)定高度等等。
另一個(gè)IE中列表的常見(jiàn)問(wèn)題出現(xiàn)在當(dāng)某個(gè) li 中的內(nèi)容是一個(gè) display: block 的錨點(diǎn)(anchor)時(shí)。在這種情況下,列表元素之間的空格將不會(huì)被忽略而且通常會(huì)顯示成額外的一行夾在每個(gè) li 之間。一種避免這種豎直方向多余空白的解決方法是賦予這些錨點(diǎn) layout。這樣還有一個(gè)好處就是可以讓整個(gè)錨點(diǎn)的矩形區(qū)域都可以響應(yīng)鼠標(biāo)點(diǎn)擊。
表格
table 總是有 layout 的,它總表現(xiàn)為一個(gè)已定義寬度的對(duì)象。在IE6中,table-layout: fixed http://msdn.microsoft.com/worksh ... ies/tablelayout.asp通常和一個(gè)寬度設(shè)為100%的表格相同,同時(shí)這也會(huì)帶來(lái)很多問(wèn)題(一些計(jì)算方面的錯(cuò)誤)。另外在IE5.5和IE6的quirks模式下還有一些別的需要注意的情況。http://dev.l-c-n.com/tables_2/
相對(duì)定位元素(r.p.)
注意,由于 position: relative 并不觸發(fā) hasLayout,所以很多諸如內(nèi)容消失或錯(cuò)位的渲染錯(cuò)誤就會(huì)因此而起。這些現(xiàn)象可能會(huì)在刷新頁(yè)面、調(diào)整窗口大小、滾動(dòng)頁(yè)面、選中內(nèi)容等情況下出現(xiàn)。原因是 IE 在據(jù)這個(gè)屬性對(duì)元素做偏移處理時(shí),卻似乎忘了發(fā)出信號(hào)讓其 layout 孩子元素進(jìn)行“重繪”(而如果是一個(gè)layout元素,那么在其重繪事件的信號(hào)鏈中,這個(gè)傳給其孩子的信號(hào)是會(huì)正常發(fā)出的)。
r.p. parent and disappearing floated child http://www.satzansatz.de/cssd/rpfloat.html
disappearing list-background bug http://positioniseverything.net/explorer/ie-listbug.html
以上是一些相關(guān)問(wèn)題的描述。作為經(jīng)驗(yàn)之談,相對(duì)定位一個(gè)元素時(shí)最好給予其 layout。再有,我們也需要檢查擁有這種結(jié)構(gòu)的父元素是否也需要 layout 或者position: relative亦或二者都需要,如果涉及到浮動(dòng)元素這點(diǎn)就十分重要。
絕對(duì)定位元素(a.p.):
包含區(qū)塊,什么是包含區(qū)塊?
理解 CSS 的包含區(qū)塊概念很重要,它回答了絕對(duì)定位元素是相對(duì)哪里定位的問(wèn)題:包含區(qū)塊決定了偏移起點(diǎn),包含區(qū)塊定義了百分比長(zhǎng)度的計(jì)算參考。
對(duì)于絕對(duì)定位元素,包含區(qū)塊是由其最近的定位祖先決定的。如果其祖先都沒(méi)有被定位,那么就使用初始包含區(qū)塊 html。
通常情況下我們會(huì)用 position: relative 來(lái)設(shè)定任意包含區(qū)塊。這就是說(shuō),我們可以讓一個(gè)絕對(duì)定位元素所參考的原點(diǎn)和長(zhǎng)度等不依賴于元素的排列順序,這可以滿足諸如“內(nèi)容優(yōu)先”這種可訪問(wèn)性概念的需要,也可以給復(fù)雜的浮動(dòng)布局帶來(lái)方便。
但是由于 layout 概念的存在,這種設(shè)計(jì)理念的效果在IE中就要打個(gè)問(wèn)號(hào)了:因?yàn)樵贗E中絕對(duì)定位只有當(dāng)其包含元素?fù)碛?layout 時(shí)才會(huì)計(jì)算正確,而且絕對(duì)定位元素的百分比寬度參考也搞錯(cuò)了對(duì)象。這里 IE5 和 IE6 的行為不同但都有問(wèn)題。IE7b2 的行為就要好很多,雖然有些小地方還是有錯(cuò)誤。總之盡可能的讓絕對(duì)元素的包含區(qū)塊擁有 layout,而且盡量讓其就是絕對(duì)定位元素的父級(jí)元素(也就是說(shuō)這個(gè)包換元素和絕對(duì)定位元素之間沒(méi)有絕對(duì)定位元素的別的祖先了)。
假設(shè)一個(gè)無(wú) layout 的父元素被相對(duì)定位了——我們就得給它賦予 layout 才能使偏移量起作用:
Absolutely Buggy II http://www.positioniseverything.net/abs_relbugs.html
假設(shè)一個(gè)未定位的父元素需要特定尺寸,而且頁(yè)面設(shè)計(jì)是基于百分比寬度的——我們就可以放棄這個(gè)想法了,因?yàn)闉g覽器支持不佳:
absolutely positioned element and percentage width http://www.satzansatz.de/cssd/tmp/apboxpercentagewidth.html
濾鏡
MS專有的濾鏡屬性 filter http://msdn.microsoft.com/workshop/author/filter/filters.asp是只適用于 layout 元素的。有些濾鏡擴(kuò)展了對(duì)象的邊界。它們會(huì)顯示出自身特有的缺陷。http://www.satzansatz.de/cssd/tmp/alphatransparency.html
對(duì)已渲染元素的重排(re-flow)
當(dāng)所有元素都已渲染完成時(shí),如果有一個(gè)因鼠標(biāo)經(jīng)過(guò)而引起的變化產(chǎn)生(比如某個(gè)鏈接的 background 有變化),IE會(huì)對(duì)其 layout 包含區(qū)塊進(jìn)行重排。有時(shí)一些元素就會(huì)因此被排到了新的位置,因?yàn)楫?dāng)這個(gè)鼠標(biāo)經(jīng)過(guò)發(fā)生時(shí),IE已經(jīng)知道了所有相關(guān)元素的寬度、偏移量等數(shù)據(jù)了。這在文檔首次載入時(shí)則不會(huì)發(fā)生,那時(shí)由于自動(dòng)擴(kuò)張的特性,寬度還無(wú)法確定。這種情況會(huì)導(dǎo)致在鼠標(biāo)經(jīng)過(guò)時(shí)頁(yè)面出現(xiàn)跳變。
Jump on :hover http://www.satzansatz.de/cssd/pseudocss.html#hoverjump
quirky percentages: the reflow http://www.positioniseverything.net/explorer/percentages.html
這些和重排問(wèn)題相關(guān)的 bug 會(huì)給百分比邊距和補(bǔ)白使用較多的流動(dòng)布局帶來(lái)不少麻煩。
背景原點(diǎn)
MS專有的這個(gè) hasLayout 還會(huì)影響背景的定位和擴(kuò)展。比如,根據(jù) CSS 規(guī)范,http://www.w3.org/TR/CSS21/colors.html#q2background-position: 0 0 應(yīng)該指元素的“補(bǔ)白邊緣(padding edge)”。而在 IE/Win 下,如果 hasLayout = false 則指的是“邊框邊緣(border edge)”,當(dāng) hasLayout=true 時(shí)指的才是補(bǔ)白邊緣:
Background, Border, hasLayout http://www.brunildo.org/test/BackgroundBorderLayout.html
邊距重疊
hasLayout 會(huì)影響一個(gè)盒子和其子孫的邊距重疊。根據(jù)規(guī)范,一個(gè)盒子如果沒(méi)有上補(bǔ)白和上邊框,那么它的上邊距應(yīng)該和其文檔流中的第一個(gè)孩子元素的上邊距重疊:
Collapsing Margins http://www.w3.org/TR/CSS21/box.html#collapsing-margins
Uncollapsing Margins http://complexspiral.com/publications/uncollapsing-margins
在 IE/Win 中如果這個(gè)盒子有 layout 那么這種現(xiàn)象就不會(huì)發(fā)生了:似乎擁有 layout 會(huì)阻止其孩子的邊距伸出包含容器之外。此外當(dāng) hasLayout = true 時(shí),不論包含容器還是孩子元素,都會(huì)有邊距計(jì)算錯(cuò)誤的問(wèn)題出現(xiàn)。
Margin collapsing and hasLayout http://www.brunildo.org/test/IEMarginCollapseLayout.html
塊級(jí)別的鏈接
hasLayout 會(huì)影響一個(gè)塊級(jí)別鏈接的鼠標(biāo)響應(yīng)區(qū)域(可點(diǎn)擊區(qū)域)。通常 hasLayout = false 時(shí)只有文字覆蓋區(qū)域才能響應(yīng)。而 hasLayout = true 則整個(gè)塊狀區(qū)域都可響應(yīng)。添加了 onclick/onmouseover 等事件的任意塊級(jí)元素也有同樣的現(xiàn)象。
Block anchors and hasLayout http://www.brunildo.org/test/IEABlock1.html
在頁(yè)面內(nèi)使用鍵盤瀏覽:探索中
當(dāng)使用 tab 在頁(yè)面中瀏覽時(shí),如果進(jìn)入了一個(gè)頁(yè)內(nèi)鏈接(in-page link),那么接下來(lái)再按的 tab 鍵就不會(huì)正常繼續(xù)了:
hasLayout Property Characterizes IE6 Bug http://jimthatcher.com/news.htm#haslayout
Keyboard Navigation and Internet Explorer http://juicystudio.com/article/ie-keyboard-navigation.php
tab 鍵會(huì)把用戶帶到(這通常是錯(cuò)誤的)其最近的 layout 祖先中的第一個(gè)目標(biāo)(如果這個(gè)祖先是由 table, div, span 或某些別的標(biāo)簽構(gòu)成)。
收縮包圍(shrink-wrapping)現(xiàn)象
給已經(jīng)有 width: auto 的元素添加某些屬性會(huì)導(dǎo)致它們?cè)谟?jì)算自身寬度時(shí)使用一種收縮包圍的算法。比如這些屬性 float: left|right, position: absolute|fixed, display: table|table-cell|inline-block|inline-table.
這些屬性造成的現(xiàn)象在IE/Win中也存在,當(dāng)然這是只對(duì)那些它支持的屬性而言。但是當(dāng)一個(gè)應(yīng)該收縮包圍的元素中包含一個(gè)擁有“l(fā)ayout”的塊級(jí)元素時(shí),在絕大多數(shù)情況下,這個(gè)孩子元素的寬度會(huì)盡可能地?cái)U(kuò)展而與其中包含的內(nèi)容無(wú)關(guān),同時(shí)也阻止了父元素的收縮包圍現(xiàn)象。
例子: http://dev.l-c-n.com/IEW2-bugs/shrinkwrap.php
一個(gè)浮動(dòng)的縱向?qū)Ш綗o(wú)序列表并沒(méi)有收縮包圍,因?yàn)槠渲械逆溄訛榱讼斜淼亩嘤嗫瞻譩ug并擴(kuò)展可點(diǎn)擊區(qū)域而擁有了 layout:a {display: block; zoom: 1;}。
這時(shí)收縮包圍現(xiàn)象只有在以下情況仍然有效:擁有 layout 的孩子元素同時(shí)也被賦予了一個(gè)特定寬度,或者這個(gè)孩子元素本身也是一個(gè)具有收縮包圍特性的元素,比如浮動(dòng)元素。
邊緣裁切
通常而言,當(dāng)一個(gè)盒子包含了諸如伸出其邊緣的內(nèi)容這種更復(fù)雜的結(jié)構(gòu)時(shí),這個(gè)容器就經(jīng)常需要“hasLayout”來(lái)避免一些渲染錯(cuò)誤。但使用這種常用方法又會(huì)在邊界處理時(shí)左右為難,因?yàn)橐粋€(gè)獲得“l(fā)ayout”的元素會(huì)變成某種自封閉的盒子。
內(nèi)部的內(nèi)容盒子會(huì)被裁切,比如使用負(fù)邊距向外移動(dòng)時(shí)。
Clipping of negative margined blocks in a hasLayout container http://dev.l-c-n.com/IEW2-bugs/min-width-clip.php
被裁掉的部分當(dāng)內(nèi)容盒子觸發(fā)了“l(fā)ayout”時(shí)可以再次出現(xiàn),但在 IE6 中需要同時(shí)擁有 position: relative 才行。IE7 在這方面要略有改觀,它不再需要額外的 position: relative 了。
堆疊,分層和 layout
IE/Win 中似乎有兩種分層和堆疊順序:
一種是(偽)試圖采用CSS的模式:Effect of z-index value to RP and AP blocks http://www.aplus.co.yu/css/z-pos/
還有一種是由“hasLayout”及其孿生兄弟“contenteditable”的行為產(chǎn)生的堆疊順序。正如在上面相對(duì)定位的例子中展現(xiàn)的那樣,在 layout 影響下的堆疊現(xiàn)象就好像 Harry Houdini (譯者注:魔術(shù)師,以紙牌魔術(shù)成名)的拿手戲法兒一樣。
兩種堆疊模式雖互不相容,但卻共存于IE的渲染引擎中。經(jīng)驗(yàn)之談:調(diào)試的時(shí)候,兩種情況都要考慮到。我們可能會(huì)有規(guī)律地在下拉菜單或者類似的復(fù)雜菜單中看到相關(guān)問(wèn)題,因?yàn)樗鼈兺鶢可娴蕉询B,定位和浮動(dòng)等諸多令人頭疼的問(wèn)題。給那些 z-index 定位的元素 layout 是一種可能的修正方法,不過(guò)也不限于此,這里只是提醒一下。
混亂的 contenteditable
如果給一個(gè) HTML 標(biāo)簽設(shè)定 contenteditable=true 屬性,比如,將會(huì)允許對(duì)該元素以及其 layout 子元素進(jìn)行實(shí)時(shí)的編輯、拖動(dòng)改變尺寸等操作。你可以把這屬性用在浮動(dòng)元素或者一個(gè)有序列表中的 layout 列表元素上看看效果。
為了對(duì)元素進(jìn)行操作(編輯它們),“contenteditable”和“hasLayout”為那些 hasLayout 返回 true 的元素引入了一套單獨(dú)的堆疊順序。
Editing Platform http://msdn.microsoft.com/librar ... mshtmleditplatf.asp繼承了 layout 概念,對(duì) layout 的誤解多是因 contenteditable 而起即可作為證明(那些某種程度上集成了IE編輯引擎的應(yīng)用軟件多暗含著對(duì)layout概念的某種強(qiáng)制向后兼容性)。
More on contenteditable http://annevankesteren.nl/2005/07/more-contenteditable
和 CSS 規(guī)范類似的地方
你的 MSIE 頁(yè)面在別的瀏覽器中一團(tuán)糟?我們可沒(méi)必要讓這種事情發(fā)生。如果使用恰當(dāng),任何好的瀏覽器都能擺平 MSIE 的頁(yè)面——只要你使用一些正確的 CSS。
利用 hasLayout 和“新的塊級(jí)格式化范圍”http://www.w3.org/TR/CSS21/visuren.html#q15之間的細(xì)微相似之處,我們可以有幾種方法在標(biāo)準(zhǔn)兼容瀏覽器中重新實(shí)現(xiàn) hasLayout 的“包含浮動(dòng)元素”http://www.w3.org/TR/CSS21/visudet.html#root-height效果,和一些“浮動(dòng)元素旁邊的元素”http://www.w3.org/TR/CSS21/visuren.html#floats所特有的效果。
Reverse engineering series http://www.gunlaug.no/contents/wd_example_01.html
Simulations http://dev.l-c-n.com/IEW/simulations.php
Quirks 模式
關(guān)于這種渲染模式的的信息,請(qǐng)參考我們的 quirks 模式 http://www.satzansatz.de/cssd/quirksmode.html章節(jié)。
Layout ——結(jié)論
整個(gè) layout 概念和一些基本 CSS 概念是不兼容的,即包含,排列,浮動(dòng),定位和層疊等。
由于頁(yè)面中元素或有或沒(méi)有 layout,會(huì)導(dǎo)致 IE/Win 的行為和 CSS 規(guī)范相違背。
擁有 layout ——另外一個(gè)引擎?
IE 的對(duì)象模型看起來(lái)是文檔模型和他們傳統(tǒng)的應(yīng)用程序模型的糅合。我之所以提到這點(diǎn)是因?yàn)樗鼘?duì)于理解IE如何渲染頁(yè)面很重要。而從文檔模型切換到應(yīng)用程序模型的開(kāi)關(guān)就是給一個(gè)元素“l(fā)ayout”。
(Dean Edwards)
有時(shí)候要解釋清楚某種行為是不可能的:就比如 hasLayout,會(huì)根據(jù)它的狀態(tài)選擇兩種不同渲染引擎的一種使用,而且每一種都有其自己的 bug 和怪異之處。
不可消除的 bug
軟件 bug 是由于在制作過(guò)程中對(duì)完整性和邏輯問(wèn)題考慮不周等人為錯(cuò)誤而導(dǎo)致的。這是人類的固有缺陷,目前還沒(méi)有什么好的解決方法。
同樣由于這種缺陷,任何試圖不重寫軟件而修復(fù) bug 的做法,都將會(huì)不可避免的導(dǎo)致軟件中出現(xiàn)更復(fù)雜的bug。
所有依賴別的軟件的軟件——當(dāng)然包括依賴操作系統(tǒng),也會(huì)同樣依賴他們的 bug。于是我們會(huì)從所有關(guān)聯(lián)的軟件中得到一連串的 bug,這也更說(shuō)明找到一個(gè)無(wú) bug 軟件是幾乎不可能的。
(Molly, the cat?)
本文創(chuàng)建于2005年6月30日,最后一次修改于2006年4月2日。
編者:
Holly Bergevin http://positioniseverything.net/
Ingo Chao http://www.satzansatz.de/css.html
Bruno Fassino http://www.brunildo.org/
John Gallant http://positioniseverything.net/
Georg S?rtun http://www.gunlaug.no/
Philippe Wittenbergh http://emps.l-c-n.com/
特別致謝給予此項(xiàng)目支持的:
Dean Edwards, and Molly ?the cat?
各種語(yǔ)言版本:
Original(English)
Brazilian? ?Portuguese by ? ? ? ?? ? ? ?? ? ? ?? ?Mauricio Samy? ?Silva
中文版本 by old9
Italian by Gabriele Romanato
相關(guān)討論:
dean.edwards.name/weblog/
[url=mailto:spam.layout@satzansatz.de]聯(lián)系作者:[/url]
版權(quán)說(shuō)明:
本文基于創(chuàng)作共用協(xié)議發(fā)布。
目錄
介紹
hasLayout —— 定義
術(shù)語(yǔ)
問(wèn)題種種
Layout 從何而來(lái)
默認(rèn) layout 元素
屬性
有關(guān)內(nèi)聯(lián)級(jí)別元素
腳本屬性 hasLayout
CSS hacks
Hack整理
關(guān)于 IE Mac 的小問(wèn)題
MSDN文檔
分析
各種情況的詳細(xì)說(shuō)明
清除浮動(dòng)和自動(dòng)擴(kuò)展適應(yīng)高度
浮動(dòng)元素旁邊的元素
列表
表格
相對(duì)定位元素(r.p.)
絕對(duì)定位元素(a.p.):包含區(qū)塊,什么是包含區(qū)塊?
濾鏡
對(duì)已渲染元素的重排(re-flow)
背景原點(diǎn)
邊距重疊
塊級(jí)別的鏈接
在頁(yè)面內(nèi)使用鍵盤瀏覽:探索中
收縮包圍(shrink-wrapping)現(xiàn)象
邊緣裁切
堆疊,分層和 layout
混亂的 contenteditable
和 CSS 規(guī)范類似的地方
Quirks 模式
Layout —— 結(jié)論
擁有 layout —— 另外一個(gè)引擎?
不可消除的 bug
因?yàn)榭紤]到IE6、IE7瀏覽器的兼容性,所以haslayout這個(gè)屬性不得不被重視,有那么多前端開(kāi)發(fā)的人和你打交道,相信你此刻也并不會(huì)寂寞了!
轉(zhuǎn)載于:https://www.cnblogs.com/huashengjam/archive/2009/09/01/1558337.html
總結(jié)
以上是生活随笔為你收集整理的寂寞的hasLayout的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。