最近在学习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