该问题应该是IE浏览器的一个bug。
解决办法:
给包含这个table的div加入 zoom:1, 便可使IE恢复标准显示格式
问题的根源应该是IE的一个特有的属性: haslayout
zoom恰巧能触发这个属性,除此之外还有postion, float, display, width, height,writing-mode,大家可以试试将那个div的“zoom:改为“display: inline-block”,结果也是正确的。
下文详细介绍haslayout属性,转载之:http://www.sharkui.com/articles/article.php?id=38。英文网址:http://www.satzansatz.de/cssd/onhavinglayout.html
转载:On having layoutOn having layout
译者注:一篇很好的文章,很久以前在blog上就推荐过,这两天断断续续花了点时间翻译了一下,推荐读读。英文原文在此。
文中所有的 layout 这个单词都未作翻译,一来本身这个单词意思就比较多,翻成啥都觉得别扭,二来它也是专有的属性,所以就意会一下吧。水平有限,很多地方都是模模糊糊地意译,发现错误欢迎留言指出。
引用一段来自Dean Edwards的评价:
I recommend that every CSS designer and DOM scripter read this. Understanding “layout” gives a huge insight into lots of other IE bugs and idiosyncrasies.
(Dean Edwards)
介绍Internet Explorer 中有很多奇怪的渲染问题可以通过赋予其“layout”得到解决。John Gallant 和 Holly Bergevin 把这些问题归类为“尺寸bug(dimensional bugs)”,意思是这些 bug 可以通过赋予相应元素某个宽度或高度解决。这便引出关于“layout”的一个问题:为什么它会改变元素的渲染特性,为什么它会影响到元素之间的关系?这 个问题问得很好,但却很难回答。在这篇文章中,我们专注于这个复杂问题会有那些方面的表现,某一方面的具体讨论和范例请参考文中给出的相关链接。
hasLayout — 定义“Layout”是一个 IE/Win 的私有概念,它决定了一个元素如何显示以及约束其包含的内容、如何与其他元素交互和建立联系、如何响应和传递应用程序事件/用户事件等,这有点类似于一个窗体的概念。
微软的开发者们认为盒状元素(box-type elements)应该具有一个“属性(property)”(这是面向对象编程中的一个概念),于是他们便使用了 layout
, 也就是 hasLayout
。
hasLayout
其实既不是一个属性更不是一个行为,而是 IE 这个渲染引擎代代继承一贯拥有的一个渲染概念,在这个概念下渲染的元素将具有一种特性。
实际上这种渲染特性在有些 HTML 元素中与身俱来,而在另外一些元素中也可以通过一些 CSS 属性将其触发为 true
,且一旦触发将不可逆转。
当我们说一个元素“拥有layout”或“得到layout”,或者说一个元素“has layout” 的时候,我们的意思是指它的微软专有属性 hasLayout
被设为了 true
。一个“layout元素”可以是一个默认就拥有 layout 的元素或者是一个通过设置某些 CSS 属性得到 layout 的元素。
而“无layout元素”,是指 hasLayout 未被触发的元素,比如一个未设定宽高尺寸的干净 div 元素就可以做为一个 “无layout祖先”。
给一个默认没有 layout 的元素赋予 layout 的方法包括设置可触发 hasLayout = true
的 CSS 属性。参考默认 layout 元素以及这些属性列表。没有办法设置 hasLayout = false
, 除非把一开始那些触发 hasLayout = true
的 CSS 属性去除。
hasLayout
的问题不管新手还是老手,不管设计师或者程序员可能都遇到过。具有 layout 的元素通常有着不同寻常而且难以预料的的显示效果,而且有时甚至会牵连到他们的孩子元素。
一个元素是否具有“layout”可能会引发如下的一些问题:
- IE 很多常见的浮动 bug 。
- 元素本身对一些基本属性的异常处理问题。
- 容器和其子孙之间的边距重叠(margin collapsing)问题。
- 使用列表时遇到的诸多问题。
- 背景图像的定位偏差问题。
- 使用脚本时遇到的浏览器之间处理不一致的问题。
上面的列表只是列出一个大概,也不完善。下面的文章将尽可能详细彻底的描述有无“layout”所带来的各种问题。
Layout 从何而来不同于标准属性,也不像某些浏览器的私有 CSS 属性,layout 无法通过某一个 CSS 声明直接设定 。也就是说没有“layout属性”这么一个东西,元素要么本身自动拥有 layout,要么借助一些 CSS 声明悄悄地获得 layout。
默认layout元素下列元素应该是默认具有 layout 的:
<html>, <body>
<table>, <tr>, <th>, <td>
<img>
<hr>
<input>, <select>, <textarea>, <button>
<iframe>, <embed>, <object>, <applet>
<marquee>
下列 CSS 属性和取值将会让一个元素获得 layout:
- 绝对定位元素的包含区块(containing block)就会经常在这一方面出问题。
- 由于 layout 元素的特性,浮动模型会有很多怪异的表现。
- 当一个内联级别的元素需要 layout 的时候往往就要用到它,这也可能也是这个 CSS 属性的唯一效果——让某个元素拥有 layout。“inline-block行为”在IE中是可以实现的,但是非常与众不同: IE/Win: inline-block and hasLayout 。
- 很多人遇到 layout 相关问题发生时,一般都会先尝试用这个来修复。
- height: 1% 就在 Holly Hack 中用到。
-
MS专有属性,无法通过校验。 不过
zoom: 1
可以临时用做调试。 - MS专有属性,无法通过校验。
position: absolute
float: left|right
display: inline-block
width: 任意值
height: 任意值
zoom: 任意值
(MSDN)
writing-mode: tb-rl
(MSDN)
在 IE7 中,overflow 也变成了一个 layout 触发器:
- 这个属性在之前版本 IE 中没有触发 layout 的功能。
- overflow-x 和 overflow-y 是 CSS3 盒模型中的属性,尚未得到浏览器的广泛支持。他们在之前版本IE中没有触发 layout 的功能。
overflow: hidden|scroll|auto
overflow-x|-y: hidden|scroll|auto
另外 IE7 的荧幕上又新添了几个 haslayout 的演员,如果只从 hasLayout 这个方面考虑,min/max 和 width/height 的表现类似,position 的 fixed 和 absolute 也是一模一样。
- ./.
- 就算设为0也可以让该元素获得 layout。
- ./.
- 即使设为0也可以让该元素的 haslayout=true
- ./.
position: fixed
min-width: 任意值
max-width: 除 none 之外的任意值
min-height: 任意值
max-height: 除 none 之外的任意值
以上结论借助 IE Developer Toobar 以及预先测试得出。
有关内联级别元素 对于内联元素(可以是默认即为内联的比如 span
元素,也可以是 display: inline
的元素)
width
和height
只在 IE5.x 下和 IE6 的 quirks 模式下触发hasLayout
。因为在 IE6 中,如果浏览器运行于标准兼容模式下,内联元素会忽略 width 或 height 属性,所以设置 width 或 height 不能在此种情况下令该元素具有 layout。zoom
总是可以触发hasLayout
,但是在 IE5.0 中不支持。
具有“layout” 的元素如果同时也 display: inline
,那么它的行为就和标准中所说的 inline-block 很类似了:在段落中和普通文字一样在水平方向和连续排列,受 vertical-align 影响,并且大小可以根据内容自适应调整。这也可以解释为什么单单在 IE/Win 中内联元素可以包含块级元素而少出问题,因为在别的浏览器中 display: inline
就是内联,不像 IE/Win 一旦内联元素拥有 layout 还会变成 inline-block。
我们这里称 hasLayout 为“脚本属性”是为了和我们熟知的 CSS 属性相区别。
注意一旦一个元素拥有了 layout,就没有办法再将其设成 hasLayout = False
了。
hasLayout-property 可以用来检测一个元素是否拥有 layout:举个例子,如果它的 id
是“eid”,那么只要在 IE5.5+ 的地址栏里输入 javascript: alert(eid.currentStyle.hasLayout)
即可检测它的状态。
IE的 Developer Toolbar 可以实时检查一个元素的当前样式;如果 hasLayout
是 true ,那么它的值显示为 “-1”。 我们可以通过实时修改一个元素的属性将“zoom(css)”设置为“1”来触发 hasLayout
以便调试。
另外一个需要注意的是“layout”会影响脚本编程。如果一个元素没有“layout”,那么clientWidth
/clientHeight
总是返回0。这会让一些脚本新手感到困惑,而且这和 Mozilla 浏览器的处理方式也不一样。不过我们可以利用这一点在 IE5.0 中检测“layout”:如果 clientWidth
是零那么这个元素就没有 layout。