标签归档:IE6

IE6中选择器的BUG

请仔细观察下面的代码,在FF中是正常显示的,但在IE6中字体变成了红色。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>TEST</title>
	<style type="text/css">
		.span.text a {
			color: red;
		}
	</style>
</head>
<body>
	<span class="text"><a href="#">IE6下是红的</a></span>
</body>
</html>

象.a.b与.a.b.c这种写法,ie6只能识别最后一个选择器,也就是.b和.c。

触发hasLayout引起的BUG

在IE6下面,很多显示的BUG都可以用触发hasLayout的方式去解决。但有种情况正好相反,触发hasLayout之后会产生显示的BUG。请看下面的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>Demo</title>
	<style type="text/css">
		#div1 {
			background: red;
			margin: 10px;
			padding: 10px;
		}
		#div2 {		
			background: gray;
			margin: 30px;
			padding: 10px;
		}
	</style>
</head>
<body>
	<div id="div1">
		<div id="div2">TEST</div>
	<div>
</body>
</html>

上面的代码在所有浏览器里是正常显示的,包括IE6。但是给#div1设定宽度之后(触发hasLayout),经过大量测试,在IE6下#div1上面的padding会消失。有兴趣的同学可以看这篇文章:IE7-/Win: Margin collapsing and hasLayout

目前解决的办法就是去掉#div1的宽度,然后在#div1外面套一层div,在这个新div上设定宽度。解决问题的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>Demo</title>
	<style type="text/css">
		#con {
			width: 400px;
		}
		#div1 {
			background: red;
			margin: 10px;
			padding: 10px;
		}
		#div2 {		
			background: gray;
			margin: 30px;
			padding: 10px;
		}
	</style>
</head>
<body>
	<div id="con">
		<div id="div1">
			<div id="div2">TEST</div>
		<div>
	</div>
</body>
</html>

IE6是支持!important的

由于本人最近沉迷于iPhone不能自拔,所以很久没有更新博客了。转入正题:

网上很多讲CSS HACK的教程都有这样的内容,如果想写一个让FF、IE7、IE8可以识别,并且IE6不能识别的CSS HACK,就用!important。造成的结果就是很多人以为!important在IE6下根本不支持,本人当时就是受害者之一。!important在CSS1中就有描述,链接如下:http://www.w3.org/TR/CSS1/#important。为什么会造成IE6不支持的假象呢,原因是IE6有BUG。在IE6中,下面的这段代码显示是不正确的。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Demo</title>
    <style type="text/css">
		div {
			width: 100px;
			height: 100px;
			background: red !important;
			background: yellow;
		}
	</style>
</head>
<body>
	<div></div>
</body>
</html>

在标准浏览器下,这个DIV应该是红色的,但在IE6下是黄色的。这个只能说是IE6的BUG,而不能说IE6完全不支持!important。如果把上面的代码改为:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Demo</title>
    <style type="text/css">
		div {
			width: 100px;
			height: 100px;
			background: red !important;
		}
		div {			
			background: yellow;
		}
	</style>
</head>
<body>
	<div></div>
</body>
</html>

怎么样,可以正常显示了吧。同理,下面的代码在IE6下也可以正确显示的。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Demo</title>
    <style type="text/css">
		div {
			width: 100px;
			height: 100px;
			background: red !important;
		}
		#div1 {			
			background: yellow;
		}
	</style>
</head>
<body>
	<div id="div1"></div>
</body>
</html>

结论:作为CSS优先级别的老大,!important是全浏览器兼容的。

消失的列表背景

IE6中设定了position: relative; float: left的容器下,如果存在着多个带有背景的列表,那么这些列表中有一部分会显示不正常,具体的表现为背景消失。例如下面的代码(请在IE6中查看):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>TEST</title>
</head>
<style type="text/css">
	#container {
		position: relative;
		float: left;
	}
	#container li {
		background: red;
	}
</style>
<body>
	<div id="container">
		<ul>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
		</ul>
		<ul>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
		</ul>
		<ul>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
			<li>Hello Kitty</li>
		</ul>
	</div>
</body>
</html>

解决的方法是给li也加上position: relative。这个BUG的具体描述,请参考:http://www.positioniseverything.net/explorer/ie-listbug.html

IE6,IE7中负缩进的问题

在IE6,IE7下面给display: inline-block的元素设置text-indent: -9999px会把这个元素以及后面的元素拉走。请在IE6和IE7下,查看演示

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>TEST</title>
	<style type="text/css">
		.bar {
			border: 1px solid;
			display: inline-block;
			height: 18px;
		}
		.bar .icon {
			display: inline-block;
			width: 16px;
			height: 16px;
			background: red;
			text-indent: -9999px;
		}
	</style>
	<!--[if lte IE 7]>
	<style type="text/css">
		.bar {
			display: inline;
		}
	</style>
	<![endif]-->
</head>
<body>
	<input type="text" />
	<div class="bar">
		<span class="icon"></span>
		<span>HELLO KITTY HELLO KITTY HELLO KITTY</span>
	</div>
</body>
</html>

在IE6,IE7下可以看到.bar里面的内容都没有了。最开始的想法是让.icon浮动来解决这个问题,可是用css hack给.icon加上float: left居然不起作用,.icon后面的文字仍然被拉走。这时候只好在blueidea求助,结果那里的版主(yoom)想法和我的一样,让.icon浮动,但是他比我多加了个display: block,最终这个BUG被修正了。正常情况下,span元素加上float之后就已经是block级别了,但就是这个display: block起了决定性的作用,按yoom的话说,真是无心插柳啊。

最终的CSS HACK为:

<!--[if lte IE 7]>
<style type="text/css">
	.bar {
		display: inline;
	}
	.bar .icon {
		display: block;
		float: left;
	}
</style>
<![endif]-->

IE6浮动引起的一些BUG

LI浮动之后换行

在一个没有设定宽度的浮动元素#floated里,有一个触发了hasLayout的子元素#content,并且#content没有设定宽度。那么#content和#floated会以100%的宽度呈现,占满这一行。例子:


(IE6的截图)

li {
	float: left;
	display: block;
}
li a {
	display: block;
	height: 30px;
	margin-right: 10px;
}
<ul>
	<li><a href="#">HELLO WORLD</a></li>
	<li><a href="#">HELLO WORLD</a></li>
	<li><a href="#">HELLO WORLD</a></li>
	<li><a href="#">HELLO WORLD</a></li>
	<li><a href="#">HELLO WORLD</a></li>
	<li><a href="#">HELLO WORLD</a></li>
</ul>

在上面的例子中,a元素触发了hasLayout,但是没有设定宽度,在IE6里会产生换行。
解决办法有下面几种:

  • 给a或者li明确的宽度。
  • 让a元素也浮动。(可能会带来新的BUG
  • 去掉height,也就是不触发hasLayout。(可能会带来新的BUG
LI中的浮动元素以阶梯的方式呈现

继续用上面的HTML做为例子,CSS变为:

ul {		
	list-style: none;
}
li a {
	float: left;
	height: 30px;
	margin-right: 10px;
}

(IE6的截图)

在标准浏览器下,如果有足够的宽度,例子中所有的a元素会构成一行。但是在IE6下面,a元素是以阶梯的方式呈现。解决的办法有下面几种:

  • 给li加上display: inline;。
  • 让li也浮动。
浮动元素文本换行

上图中的li没有设置宽度,当容器的宽度不够时,正常情况下应该是li下沉,另起一行。但是在IE6下面却是li里面的文本换行,导致混乱的布局。下面是产生BUG的CSS:

ul {		
	list-style: none;
}
li {
	float: left;
}
li a {
	margin-right: 10px;
}

(IE6的截图)

解决的办法有下面几种:

  • 加上white-space: nowrap;
  • 给浮动元素(上面的例子为li)一个确切的宽度值。
  • 在IE6下用hack,让li以inline-block的方式呈现。(如果display: inline-block不起作用,点击这里

(待续……)

断头台(Guillotine)

Guillotine是一个在IE6下的BUG。表现的形式为:当鼠标放在一些链接上,浮动元素的下部会被裁剪掉。请用IE6查看演示

如何触发

如果让Guillotine“正常工作”,要满足下面几点:

  1. 有一个block级的包含元素(#container),不要触发layout
  2. 在#container里有一个浮动的元素(#floated)。
  3. 在#float的后面有一些a标签,并且在a:hover里面要改变background。

其中第三点改变background很重要,经过测试如果不改变background,则在上面的条件下不会触发这个BUG。

如何修复

修复这个BUG有下面几个方法:

  1. 让#container触发layout。
  2. 在a:hover里面不要改变background。
  3. 在#container的后面添加一个清除浮动的元素。如:
    <div id="container">
    	<div id="floated">
    	...
    	</div>
    	<a href="#">断头台</a><br />
    	...
    </div>
    <div style="clear: both"></div>
    
  4. 在#floated的后面加上清除浮动的元素。(不推荐,会带来新BUG。)

IE6中select元素z-index的bug

通常的情况下,IE6中的select元素永远是在最上面的,即使覆盖在它上面的元素的z-index再大也不起作用。比如说有个id为div1的元素绝对定位在select元素的上面。这里假设div1的z-index比select的大,但在IE6里看上去还是select在上面,div1并不能覆盖住它。为了解决这个问题,只能在div1和select中间插入一个和div1的位置以及大小一样的iframe来达到覆盖select的效果。

网上有个叫bgiframe的jQuery插件可以达到这个效果。拿上面的例子来说,它动态的在div1里插入一个透明的iframe,iframe的尺寸是用IE特有的CSS expression计算的,这么做的好处在于iframe随时都可以保持和div1同样大小,缺点是CSS expression太占资源了,可能会导致浏览器假死,如果覆盖在select上的元素的尺寸在运行时不会改变的话,就没必要用CSS expression。所以把bgiframe的代码改了一下。

改过之后的代码,记录一下:

(function($){
  $.fn.bgIframe = $.fn.bgiframe = function(s) {
    if ($.browser.msie && /6.0/.test(navigator.userAgent)) {
      s = $.extend({
        top    : 'auto',
        left    : 'auto',
        width   : 'auto',
        height  : 'auto',
        src     : 'javascript:false;'
      }, s || {});
      var prop = function(n) {
        return n&&n.constructor==Number?n+'px':n;
      };
      return this.each(function() {
        if ( $('> iframe.bgiframe', this).length == 0 ) {
          var iframe = $('<iframe frameborder="0" tabindex="-1"></iframe>')
          .addClass("bgiframe")
          .css({
            display: 'block',
            position: 'absolute',
            zIndex: '-1',
            opacity: 0,
            top: s.top === 'auto'?
              ((this.clientTop || 0)*-1 + 'px'): prop(s.top),
            left: s.left === 'auto'?
              ((this.clientLeft || 0)*-1 + 'px'): prop(s.left),
            width: s.width === 'auto'?
              (this.offsetWidth + 'px'): prop(s.width),
            height: s.height === 'auto'?
              (this.offsetHeight + 'px'): prop(s.height)
          })
          .insertBefore(this.firstChild);
        }
      });
    }
    return this;
  };
})(jQuery);