Kampfer的记事本

新blog:www.kampfer-lw.com

导航

脱离文档流的容器,IE下宽度自适应的bug(转)

Posted on 2010-09-02 22:50  Kamfper  阅读(1096)  评论(0编辑  收藏  举报

现象

测试页面:ie_hasLayout_width_bug.html

正常情况下,没有设定宽度的浮动容器test-wrap,当包含的block元素test-box也没有设定宽度时,test-box的宽度会和test-wrap保持一致:
ie_hasLayout_width_bug_1.png
其中test-wrap的宽度取决于所包含的子元素的最大宽度。

但在IE7下,test-box的宽度塌缩到最小了
ie_hasLayout_width_bug_2.png

IE6下,test-box的宽度则扩展到和浏览器窗口一样宽:
ie_hasLayout_width_bug_3.png

分析

上面的测试页面,只给出了容器浮动时的场景。实际上,绝对定位的容器也有此问题。浮动和绝对定位有个共同点,就是让元素脱离了文档流。如果没有脱离文档流,比如相当定位,则无此bug。

对于脱离文档流的容器,当容器没有设定宽度时,其宽度会尽量小,取决于容器内子节点的最大宽度。
对于该容器内的block元素,当没有设定宽度时,正常情况下,其宽度会自动和容器的宽度保持一致。

注意测试页面中的第4种情景,当不给test-box设定高宽,保持无hasLayout时,test-box的宽度在IE6和IE7下都是正确的。

第1种情景,给test-box设定了高度,实际上是触发了test-box的hasLayout. 这是引发IE6和IE7下bug的本因。IE7的处理方式是,将容器内有hasLayout的block元素,也塌缩到宽度最小。IE6的处理方式则是,一旦容器内的block元素有了hasLayout,就会无视容器的限制,其宽度会直接越级与document.body保持一致,太不尊重领导了-.-

第2种和第3种情景,给test-wrap设定了宽度。一旦设定了宽度,IE7乖乖的都ok了。恼人的是,当给容器设定的宽度容纳不了里面的block元素时,IE6依旧非常不尊重领导,直接将领导的办公室扩建了。

总结成一句话:当脱离文档流的容器没设定宽度时,在IE7下,容器内触发了hasLayout但没设定宽度的block元素,会很谦虚的缩在一角;而在IE6下,容器内的元素一旦有了hasLayout,就会不尊重领导,直接越级与领导的领导保持一致;即便设定了宽度,也会将直属领导的办公室扩建。

解决方法

知道了缘由,解决方法很自然就能想到:

  • 方法一:给容器设定宽度,并且宽度值能包容所有block子元素,以防止IE6扩建。
  • 方法二:给容器内的子元素设定宽度,让它们自己管好自己,不给领导找麻烦。
  • 方法三:当容器内的元素宽度都未知时,通过js去动态计算子元素的最大宽度。算好后,赋值给容器。比如用 Ext.util.TextMetrics 就能干这事。