最近在學習CSS的display屬性時,遇到一個在IE6/7下html塊級元素設置inline-block屬性的兼容性問題,因而就查資料,網上不少關於這個問題的解答,大體的描述以下:[1]css
IE六、IE7支持對html行內元素設置inline-block。實際上只是看起來支持而已,IE六、IE7並不識別inline-block這個屬性值,只是觸發了layout,讓行內元素有了inline-block的表徵,好比說:行內顯示且可設置寬高等等。html
而對html塊級元素設置inline-block,也只是觸發了layout,對塊級元素設置行內塊級屬性的目的沒有達到。react
那麼在IE六、IE7下,怎麼實現塊級元素的inline-block屬性值設置呢?
常見有2種方法:chrome
先使用display:inline-block屬性觸發塊元素,而後再定義display:inline,讓塊元素呈遞爲行內對象(兩個display 要前後放在兩個CSS聲明中才有效果,這是IE的一個經典bug,若是先定義了display:inline-block,而後再將display設回 inline或block,layout不會消失),代碼以下:express
div {display:inline-block;}
div {display:inline;}瀏覽器
直接讓塊元素設置爲行內對象呈遞(設置屬性display:inline),而後觸發塊元素的layout(如:zoom:1 或float屬性等),代碼以下:網絡
div { display:inline-block; _zoom:1;_display:inline;}/*推薦IE6*/
div { display:inline-block; *zoom:1;*display:inline;}/*推薦IE6或IE7*/app
但是,總以爲有些地方不明白。ssh
咱們用IETester來測試一下,IE6/IE7/IE9三個版本瀏覽器對行內和塊級元素實際的顯示狀況。編輯器
首先,給出HTML部分代碼,這裏的one和four對應的元素只是做爲參照物,中間兩個纔是實際操做的元素:
<span id="one">one</span> <span id="two">two</span> <div id="three">three</div> <span id="four">four</span>
css部分代碼以下:
#one { background-color: orangered; } #two { background-color: lime; height: 2em; } #three { background-color: black; color: white; height: 3em; } #four { background-color: skyblue; }
IE6/IE7/IE9對應的顯示狀況:
很明顯,這裏三者沒啥區別。
而後,就是修改了。
#two { background-color: lime; height: 2em; display: inline-block; }
IE6/IE7/IE9對應的顯示狀況:
小結:咱們發現雖然IE6/IE7的行內元素設置inline-block後顯示的結果代表有塊級元素顯示寬高的「能力」,可是跟IE9上顯示的有區別呢,我又在在chrome上試了一下,跟IE9的同樣。IE9和chrome對inline-block是徹底支持的,這說明什麼?說明可能IE6/IE7並非像IE9和chrome那樣實現inline-block設置的。
#three { background-color: black; color: white; height: 3em; display: inline-block; }
IE6/IE7/IE9對應的顯示狀況:
小結:咱們很明顯能夠看出IE6/IE7不支持塊級元素設置inline-block。
#three { background-color: black; color: white; height: 3em; display: inline-block; *display: inline; }
IE6/IE7/IE9對應的顯示狀況:
小結:此次是塊級元素three得到了inline的屬性值,但是IE6/IE7下block屬性「丟了」。也就是設置inline-block失敗,*display:inline;沒起做用。
#three { background-color: black; color: white; height: 3em; display: inline-block; } #three { *display: inline; }
IE6/IE7/IE9對應的顯示狀況:
小結:總算把塊級元素設置成inline-block了,可是爲什麼IE6/IE7跟IE9的顯示結果仍是不同呢?是否是跟第一步中行內元素設置inline-block的狀況很像呢?
#three { background-color: black; color: white; height: 3em; display: inline-block; _zoom:1; *display: inline; }
IE6/IE7/IE9對應的顯示狀況:
小結:此次IE7直接不顯示出塊級的效果了。爲什麼IE6就能夠,哪裏出問題了?
#three { background-color: black; color: white; height: 3em; display: inline-block; *zoom:1; *display: inline; }
IE6/IE7/IE9對應的顯示狀況:
小結:能夠看到,此次顯示的效果跟第四步的同樣的了。結合第五步的結果,能夠說明display前面的星號(*)和下劃線(_)的做用對於IE6和IE7有區別。
那麼問題真的解決掉了麼?
IE六、IE7是否真的支持inline-block屬性值?爲什麼說支持行內元素的設置inline-block,又說只是「表徵」呢?
「觸發layout」中這個layout又是指的什麼,觸發的原理是什麼?
_zoom和_display具體是什麼狀況下使用的。
*display和_display前面的星號(*)和下劃線(_)有什麼做用?
首先來看下MSDN上關於inline-block屬性值的解釋:
將對象呈現爲行內元素,但將對象的內容呈現爲塊元素。相鄰的行內元素將呈如今同一行上,容許有空格。[2]
然而並不能用於解答「表徵」inline-block的問題,好吧,那就當鞏固知識點好了。
再來瞧瞧quirks mode上關於inline-block的解釋:
IE 6/7 accepts the value only on elements with a natural display: inline.[3]
也就是說IE6/7是隻對原生行內元素起做用,可是爲什麼上面的實例中第一步顯示的結果跟IE9和chrome的結果不同呢?哦,對了,IE9和chrome是按照w3c標準支持inline-block屬性值的。而前面說的對行內元素起做用或者說只有行內元素可以接受這個inline-bloc屬性值,但並未說明是嚴格按照w3c標準支持的呀。有貓膩!
因而乎,根據「觸發layout」就到了一個關於hasLayout這個(既)微(又)軟專有屬性的相關文章。
hasLayout是個什麼鬼呢?這一切得從微軟專有概念「layout」講起。
「Layout」 is an IE/Win proprietary concept that determines how elements
draw and bound their content, interact with and relate to other
elements, and react on and transmit application/user events.[4]
也就是說在IE下面layout是跟元素「隨行」,每一個元素都有個layout,只不過有些元素是自然顯現出layout的或者說是自然觸發了layout的(自帶光環啊!摔),有些沒有自然觸發layout。而觸發layout時,會有微軟專有屬性hasLayout賦值爲true的行爲,hasLayout=true,並且仍是不可逆的,置於怎麼把不可逆的「逆」回去,引文的「重度參考」裏有,就再也不探討了。
當觸發layout後,這個元素就能夠像塊級元素設置寬高邊界等等屬性了,可是必定要記住這跟w3c標準的塊級屬性的區別。由於觸發layout後並不徹底支持w3c標準的inline-block,在IE6/7下對塊級元素設置inline-block,會覆「忽視」塊級元素原生的display屬性。也就是說對於一個塊級元素直接設置inline-block並不能達到預期的目的。因此才須要用到*display:inline; *zoom:1; 這等IE hack。
可是爲什麼行內元素直接設置,inline-block就不會被「忽視」原生的display屬性呢?這還得從IE6標準版之前的版本提及。在那個「年代」,設置行內元素是能夠設置寬高的,沒錯,你沒看錯,是能夠設!置!寬!高!的!也就是微軟家的行內元素其實一出生就是個行內塊級元素,因此纔會有IE6標準版之前的版本的「尺寸bug」。
不過,人家也確實不是徹底按照W3C標準套路走的,微軟本身搞出來的一套東西本身玩,你能說啥。IE6標準版之前的版本下行內元素是原生帶有W3C標準中display:inline-block;的屬性值的,我試過,確實是醬紫的,不信請看:
#two { background-color: lime; height: 2em; } #three { background-color: black; color: white; height: 3em; display: inline-block; *zoom:1; /*這裏能夠省略,至於爲何,我說測試出來就是這樣子,會被打死麼*/ *display: inline; }
可是,從IE6標準版開始,行內元素設置寬高是會被忽略的,因此看起來還像是有W3C標準中display:inline;屬性的特性。
綜上,咱們能夠解決第一個和第二個衍生問題了。對於IE六、IE7是否真的支持inline-block屬性值,首先要明確咱們常說的inline-block是W3C標準的屬性值,是明確的區分行內元素、塊級元素和行內塊級元素的。可是微軟不玩那一套,搞出個layout,經過一些特定的CSS屬性來觸發,表現爲hasLayout=true,來使得一個元素有了W3C標準中inline-block的一些特性。
接下來,再說_zoom和_display以及*zoom和*display。這裏先後的區別在於星號()和下劃線(_)。其實下劃線(_)是隻有IE6才能識別,而星號()是隻有IE6和IE7可識別,做用就是用於區分不一樣瀏覽器的。[5] 沒錯就是區分屌絲和高帥富的!
而後,爲什麼要用_zoom和_display或者*zoom和*display呢?首先zoom又是微軟的專有屬性,日常多用zoom:1;來進行調試,其次zoom始終能夠觸發layout。[6] 而_display:inline;或者*display:inline;是爲了讓元素從新得到display:inline;的屬性。也就是這二者已經能夠完成與W3C標準中inline-block類似的特性了,那開頭第二個解決方案爲什麼前面還要加個display:inline-block;這不畫色添足麼?no,no,no。前面說了,這兩個屬性聲明只是分別適用與IE6和IE6+IE7,對於其餘瀏覽器是能夠識別且按照W3C標準準確實現inline-block的,所以,纔有了開頭的代碼:
display:inline-block; _zoom:1;_display:inline;
至此,第三和第四個衍生問題也解決了,有沒有以爲對IE六、7的display屬性的瞭解又有點增加呢?也不枉我花了好多事時間去查資料,碼文章啦。
以上爲根據一些網絡資料加上部分我的實際測試得出的我的觀點,或有錯漏之處,還請指出以便交流學習。本人初發技術貼,也許水了點,還請輕拍。
本文章對參考目錄中的第一篇文章參考度很高,而且也以爲第一篇文章很不錯,找時間用我「靠譜」的英語來翻譯一下,順便加深一下對IE「layout」的理解。
另外,找到一個測試IE塊級元素inline-block的網頁:IE block level element inline-block hack
IE瀏覽器兼容性測試軟件:IETester;
編輯器sublime text 3;
MSDN關於display的解釋;
quirks mode上關於inline-block的兼容性解釋:The display declaration