【CSS學習筆記】對於IE六、IE7下display: inline-block; 的兼容問題的探討

初始問題描述

最近在學習CSS的display屬性時,遇到一個在IE6/7下html塊級元素設置inline-block屬性的兼容性問題,因而就查資料,網上不少關於這個問題的解答,大體的描述以下:[1]css

  1. IE六、IE7支持對html行內元素設置inline-block。實際上只是看起來支持而已,IE六、IE7並不識別inline-block這個屬性值,只是觸發了layout,讓行內元素有了inline-block的表徵,好比說:行內顯示且可設置寬高等等。html

  2. 而對html塊級元素設置inline-block,也只是觸發了layout,對塊級元素設置行內塊級屬性的目的沒有達到。react

那麼在IE六、IE7下,怎麼實現塊級元素的inline-block屬性值設置呢?
常見有2種方法:chrome

  1. 先使用display:inline-block屬性觸發塊元素,而後再定義display:inline,讓塊元素呈遞爲行內對象(兩個display 要前後放在兩個CSS聲明中才有效果,這是IE的一個經典bug,若是先定義了display:inline-block,而後再將display設回 inline或block,layout不會消失),代碼以下:express

    div {display:inline-block;}
    div {display:inline;}瀏覽器

  2. 直接讓塊元素設置爲行內對象呈遞(設置屬性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設置display:inline-block;聲明

#two {
    background-color: lime;
    height: 2em;
    display: inline-block;
}

IE6/IE7/IE9對應的顯示狀況:
行內元素設置inline-block
小結:咱們發現雖然IE6/IE7的行內元素設置inline-block後顯示的結果代表有塊級元素顯示寬高的「能力」,可是跟IE9上顯示的有區別呢,我又在在chrome上試了一下,跟IE9的同樣。IE9和chrome對inline-block是徹底支持的,這說明什麼?說明可能IE6/IE7並非像IE9和chrome那樣實現inline-block設置的。

第二步,對塊級元素three設置display:inline-block;聲明

#three {
    background-color: black;
    color: white;
    height: 3em;
    display: inline-block;
}

IE6/IE7/IE9對應的顯示狀況:
塊級元素設置inline-block
小結:咱們很明顯能夠看出IE6/IE7不支持塊級元素設置inline-block。

第三步,對上述的塊級元素再添加*display:inline;聲明

#three {
    background-color: black;
    color: white;
    height: 3em;
    display: inline-block;
    *display: inline;
}

IE6/IE7/IE9對應的顯示狀況:塊級元素設置inline-block+inline
小結:此次是塊級元素three得到了inline的屬性值,但是IE6/IE7下block屬性「丟了」。也就是設置inline-block失敗,*display:inline;沒起做用。

第四步,將上述後添加的*display:inline;放於一個獨立的CSS規則中

#three {
    background-color: black;
    color: white;
    height: 3em;
    display: inline-block;
}
#three { *display: inline; }

IE6/IE7/IE9對應的顯示狀況:
塊級元素設置inline-block+獨立的inline
小結:總算把塊級元素設置成inline-block了,可是爲什麼IE6/IE7跟IE9的顯示結果仍是不同呢?是否是跟第一步中行內元素設置inline-block的狀況很像呢?

第五步,換個方法,給第三步的塊級元素再添加_zoom:1;聲明

#three {
    background-color: black;
    color: white;
    height: 3em;
    display: inline-block;
    _zoom:1;
    *display: inline;
}

IE6/IE7/IE9對應的顯示狀況:
塊級元素設置inline-block+_zoom
小結:此次IE7直接不顯示出塊級的效果了。爲什麼IE6就能夠,哪裏出問題了?

第六步,給第三步的塊級元素再添加*zoom:1;聲明

#three {
    background-color: black;
    color: white;
    height: 3em;
    display: inline-block;
    *zoom:1;
    *display: inline;
}

IE6/IE7/IE9對應的顯示狀況:
塊級元素設置inline-block+*zoom
小結:能夠看到,此次顯示的效果跟第四步的同樣的了。結合第五步的結果,能夠說明display前面的星號(*)和下劃線(_)的做用對於IE6和IE7有區別。

那麼問題真的解決掉了麼?

衍生問題

  1. IE六、IE7是否真的支持inline-block屬性值?爲什麼說支持行內元素的設置inline-block,又說只是「表徵」呢?

  2. 「觸發layout」中這個layout又是指的什麼,觸發的原理是什麼?

  3. _zoom和_display具體是什麼狀況下使用的。

  4. *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;
}

IE5.5行內元素自帶inline-block
可是,從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

測試工具

  1. IE瀏覽器兼容性測試軟件:IETester

  2. 編輯器sublime text 3;

參考

  1. 重度參考:On having layout — the concept of hasLayout in IE/Win

  2. IE6/IE7下:inline-block解決方案

  3. IE css hack 彙總

  4. CSS hack大全

  5. MSDN關於display的解釋;

  6. quirks mode上關於inline-block的兼容性解釋:The display declaration

相關文章
相關標籤/搜索