【转】IE6下DIV容器中双Float元素字符重影bug(IE6重复文字bug)

转载前说明:感谢作者,我终于找到个说法了,之前因为没有相关资料一直是通过改变代码结构来解决该问题的,现在看到这些总结也总算不会无计可施,同样碰到问题的同学有福了。

转载自:http://www.yuzi.me/Share/ie6floatbug.html

ie6floatbug1

IE7 的web标准之道IE历来被web标准的拥护者所诟病,而当FireFox横空出世以后,更多的网页制作者开始关注web标准设计。看着FireFox的 市场占有率不停的上升,微软终于推出了IE7。但IE7是否真的能够力挽狂澜,是否真的能够得到用户的信任,是否真的能够得到网页设计者的认可呢?

估 计很多的朋友都是因为这个华丽的“重复文字”一词进来的,其实这纯粹是一个bug作为。这个bug在国际上比较获得认可的名字叫做——“IE6重复文字 bug”。这是一个非常好玩但是有很令人摸不到头脑的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>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<meta name=”author” content=”Yuzi,煜子,网页设计师网站” />
<meta name=”Copyright” content=”Yuzi,煜子” />
<title>IE6重复文字bug</title>
</head><body><div style=”width:200px; height:100px; padding-left:70px;”><div style=”float:left;”></div>
<!–如果是IE6,你将多看到一个“影”字–>
<div style=”float:left; width:200px;”>IE6下DIV容器中双Float元素字符重影</div>
</div>
</body>

下面是测试页面分别在IE6,IE7,IE8,FireFox(火狐浏览器),Chrome(谷歌浏览器),Oepra以及Safari(苹果浏览器)中显示效果截图

ie6floatbug2

通过截图,你会惊讶的看到在IE6中,多出了一个“影”字。下面来讲讲出现这个“影”字的一些条件(bug重现条件)

一个容器包含2两个具有“float”样式的子容器。

第二个容器的宽度大于父容器的宽度,或者父容器宽度减去第二个容器宽度的值小3(说到3,这里稍微多说一句——IE7还修正了IE6中的一个bug,bug名字就叫做“3像素bug”)

在第二个容器前存在注释(这也是为什么此bug也叫做“IE6注释bug”的原因)

为何会出现重影

bug虽然的的确确的存在,但是为什么会出现这样的bug依然没有统一的定论。不同的高手也是各执一词,谁也说服不了谁。真正的原因也许只有当时的IE6团队才能道出来,但是现在仍然没有官方的说法。下面列出来的这两种说法,只是现在网上认可度比较高的而已。

说法一:

IE6浏览器对<!– –>注释的解释存在bug引起的。“3像素bug”的扩展后遗症。

说法二:

其他的一些说法,如何消灭重影 引起的原因,也许我们可以不知道,但是如何消除却是我们一定要关注的。”重影bug”已经在IE7中得到修正,在FireFox和Opera中也不会出现,所以bug的修正主要是针对IE6的。

针对于上文中讲到的“bug重现条件”,如果要修正bug,只要让任何一个条件满足即可。有些网友对IE6 重影bug做出了一些想法及议论。

解决方法一:

改变结构,不出现【一个容器包含2两个具有“float”样式的子容器】的结构。
此解决方案的评论:疯了!因噎废食的做法。

解决方法二:

减小第二个容器的宽度,使父容器宽度减去第二个容器宽度的值大于3,例如将本文示例中第二个子容器的宽度改为197px。
此解决方案的评论:在满足页面布局的前提下可以使用。但是当情况比较复杂的时候,可能实施起来比较困难。

解决方法三:

去掉所有的注释。
此解决方案的评论:最直接的做法,但是“没有注释的代码”,的确不是一个好的代码写作习惯。

解决方法四:

修正注释的写法。将 <!– 这里是注释内容 –>写成<!–[if !IE]>这里是注释内容<![endif]–>
此解决方案的评论:还不错的解决方案,但是并不是每个人都对<!–[if !IE]>这里是注释内容[endif]–>这种注释写法很欣赏。

解决方法五:

在第二个容器后面加一个或者多个<div style=”clear”></div>来解决。
此解决方案的评论:另人感觉很不爽的解决方案,但是的确能解决,影响网页效率。

关于此bug的一些文章资料,其实很早以前就有外国的朋友关注过这个bug,而且在中国也有过一些朋友关注过这个bug。我在写这篇文章的时候,也一定程度上参照了他们的研究成果,在此向研究此问题的前辈们表示感谢。

覆盖select,使之不可操作

自定义的层给select遮挡住是一个老问题了,不过可喜的是ie7和ff都已经支持select的zIndex,只要给层设定高的zIndex就能覆盖select了,可惜对于ie6这个问题还是需要解决。

覆盖select据我所知有两个比较好的方法:

1,显示层时,先隐藏select,关闭层时再重新显示;

2,用一个iframe作为层的底,来遮住select。

方法1应该都明白,方法2就是利用iframe可以覆盖select的特性,只要把一个iframe作为层的底部就可以覆盖下面的select了,程序中是这样使用的:this.Lay.innerHTML = ‘<iframe style=”position:absolute;top:0;left:0;width:100%;height:100%;filter:alpha(opacity=0);”></iframe>’可以看出这个透明的iframe也以同样覆盖整个页面,如果是有内容显示的页面最好设置z-index:-1;确保iframe在层的底部。个人觉得使用方法2比较好,但始终是改变了页面结构,有时会比较难控制,至于方法1就比较容易方便。

修正IE6不支持position:fixed的问题

众所周知IE6不支持position:fixed,这个bug与IE6的双倍margin和不支持PNG透明等bug一样臭名昭著。前些天我做自己的博客模板的时候,遇到了这个问题。当时就简单的无视了IE6——尽管有几个使用IE6的朋友,一起BS我……但是对于大项目或商业网站,如果有用到这个属性的时候,是不可能直接无视的。

你是如何让position:fixed在IE6中工作的?

本文所使用的技巧是用了一条Internet Explorer的CSS表达式(expression)。你不可以直接使用该表达式,因为它可能会因为缓存而不更新。解决这一点的最简单的方式是使用eval包裹你的语句。

如何解决“振动”的问题?

显然IE有一个多步的渲染进程。当你滚动或调整你的浏览器大小的时候,它将重置所有内容并重画页面,这个时候它就会重新处理css表达式。这会引起一个丑陋的“振动”bug,在此处固定位置的元素需要调整以跟上你的(页面的)滚动,于是就会“跳动”。

解决此问题的技巧就是使用background-attachment:fixed为body或html元素添加一个background-image。这就会强制页面在重画之前先处理CSS。因为是在重画之前处理CSS,它也就会同样在重画之前首先处理你的CSS表达式。这将让你实现完美的平滑的固定位置元素!

这个方案并不是我提供的。我是在网上的某个地方读到这些的。如果你知道是谁原创了这个方法,请告诉前端观察。

我发现的另外一个小技巧是,你根本无需一个真实的图片!你可以使用一个about:blank替代一个spacer.gif图片,而且它工作的同样出色。

CSS Code123456789101112/*让position:fixed在IE6下可用! */

.fixed-top/* 头部固定 */{position:fixed;bottom:auto;top:0px;}

.fixed-bottom/* 底部固定 */{position:fixed;bottom:0px;top:auto;}

.fixed-left/* 左侧固定 */{position:fixed;right:auto;left:0px;}

.fixed-right/* 右侧固定 */{position:fixed;right:0px;left:auto;}/* 上面的是除了IE6的主流浏览器通用的方法 */

* html,* html body /* 修正IE6振动bug */{background-image:url(about:blank);background-attachment:fixed;}

* html .fixed-top/* IE6 头部固定 */{position:absolute;bottom:auto;top:expression(eval(document.documentElement.scrollTop));}

* html .fixed-right/* IE6 右侧固定 */{position:absolute;right:auto;left:expression(eval(document.documentElement.scrollLeft+document.documentElement.clientWidth-this.offsetWidth)-(parseInt(this.currentStyle.marginLeft,10)||0)-(parseInt(this.currentStyle.marginRight,10)||0));}

* html .fixed-bottom/* IE6 底部固定 */{position:absolute;bottom:auto;top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)));}

* html .fixed-left/* IE6 左侧固定 */{position:absolute;right:auto;left:expression(eval(document.documentElement.scrollLeft));}

 

【转】使IE6下PNG背景透明的七种方法任你选

PNG图像格式介绍:

PNG是20世纪90年代中期开始开发的图像文件存储格式,其目的是企图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。流式 网络图形格式(Portable Network Graphic Format,PNG)名称来源于非官方的“PNG’s Not GIF”,是一种位图文件(bitmap file)存储格式,读成“ping”。PNG用来存储灰度图像时,灰度图像的深度可多到16位,存储彩色图像时,彩色图像的深度可多到48位,并且还可 存储多到16位的α通道数据。

IE6下PNG背景透明的显示问题

PNG格式比起GIF来表现色彩更丰富,特别是表现渐变以及背景透明的渐变要比GIF格式出色很多,目前,最新的浏览器基本上都支持PNG格式。但是IE6不支持PNG背景透明,会显示一个灰色的框。

IE6下PNG背景透明的解决办法

.pngImg { background:url(image.png); _background:url(image.gif);}
注意上文的_号,目前IE7,8以及Firefox浏览器等都不支持此CSS语法,只有IE6识别。因此,其他浏览器会调用PNG,而IE6刚调用GIF。

二.滤镜filter解决IE6下背景灰

background:url(a.png) repeat-x 0 0; _background:none; _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=”a.png” ,sizingMethod=”crop”);
上面的原理是其他调用PNG,IE6,则先设背景没有,然后调用滤镜使之显示PNG图片。

缺陷:IE6下背景无法平铺,这个问题很严重。同时在性能上也有小问题,页面中次数不是很多的时候该办法还是可行的。

AlphaImageLoader滤镜会导致该区域的链接和按钮无效,解决的办法是为链接或按钮添加:position: relative;这样条代码,使其相对浮动。AlphaImageLoader无法设置背景的重复,所以对图片的切图精度会有很高的精确度要求。

解决IE下的链接无效可用最后面的方法:

三.利用JS解决html中的img(插入在网页中的png图像)png背景灰问题

页面中插入一段js即可。原理同上,只是将img标签用<span>标签替换掉,并且通过滤镜设置该<span>标签的background。它会将所有插入的PNG都如此处理。
<!–[if IE 6]>
<script>
function correctPNG()
{
for(var i=0; i<document.images.length; i++)
{
var img = document.images[i];
var imgName = img.src.toUpperCase();
if (imgName.substring(imgName.length-3, imgName.length) == “PNG”)
{
var imgID = (img.id) ? “id='” + img.id + “‘ ” : “”;
var imgClass = (img.className) ? “class='” + img.className + “‘ ” : “”;
var imgTitle = (img.title) ? “title='” + img.title + “‘ ” : “title='” + img.alt + “‘ “;
var imgStyle = “display:inline-block;” + img.style.cssText;
if (img.align == “left”) imgStyle = “float:left;” + imgStyle;
if (img.align == “right”) imgStyle = “float:right;” + imgStyle;
if (img.parentElement.href) imgStyle = “cursor:hand;” + imgStyle;
var strNewHTML = “<span “+ imgID + imgClass + imgTitle + “style=”” + “width:” + img.width + “px; height:” + img.height + “px;” + imgStyle + “;”
+ “filter:progid:DXImageTransform.Microsoft.AlphaImageLoader” + “(src='” + img.src + “‘, sizingMethod=’scale’);”></span>”;
img.outerHTML = strNewHTML;
i = i-1;
}
}
}
window.attachEvent(“onload”, correctPNG);
</script>
<![endif]–> ​

四.调用iepngfix.htc解决IE6PNG背景灰及拉伸问题

此方法来自:http://www.twinhelix.com/css/iepngfix/ 此方法基于Winodws平台,在Linux下不支持htc,没有验证过,但有网友发文证实。

以下片段添加至css文件

<div class=”pngImg”>PNG背景图片</div> <img src=”png图片” class=”pngImg” alt=””>
详细的应用方法这里就不介绍啦。

在逼不得已且身不由己必须使用PNG的情况下,这种方法应该是比较优秀的,虽然不能完美的解决IE6的平铺,但是至少是实现了拉伸,使得很多情况下可以代替平铺来使用。当然效率的问题任然是存在

五.让“块”透明的方法

.div { FILTER: alpha(opacity=20); moz-opacity: 0.2; opacity: 0.2;}
测试IE6,IE7,IE8,FF2,FF3均通过。提示:IE6,IE7需设置一个宽度(100%也行),否则看不到效果。

六.DD_belatedPNG,解决IE6不支持PNG绝佳方案

整个互联网上解决这个IE6的透明PNG的方案也是多不胜数,从使用IE特有的滤镜或是e xpression,再到javascript+透明GIF替代.但是这些方法都有一个缺点,就是不支持CSS中backgrond-position与 background-repeat.

而我今天介绍DD_belatedPNG,只需要一个理由,就是它支持backgrond-position与background-repeat.这是其他js插件不具备的.同时DD_belatedPNG还支持a:hover属性,以及<img>.

看Demo: http://www.ediyang.com/demo/DD_Png/

原理
这个js插件使用了微软的VML语言进行绘制,而其他多数解决PNG问题的js插件用的是AlphaImageLoader滤镜.

使用方法
1.在这里下载DD_belatedPNG.js文件.
http://dillerdesign.com/experiment/DD_belatedPNG/#download

2.在网页中引用,如下:
<!–[if IE 6]>
<script src=”DD_belatedPNG.js” mce_src=”DD_belatedPNG.js”></script>
<script type=”text/javascript”>     /* EXAMPLE */   DD_belatedPNG.fix(‘.png_bg’);   /* 将 .png_bg 改成你应用了透明PNG的CSS选择器,例如我例子中的’.trans’*/   </script> <![endif]–>
3.有2种调用函数,一种是DD_belatedPNG.fix(),如上代码.另一种是fix(),这中方法需要在函数内指出css选择器名.
使用a:hover请留意
5-25 更新:如果你也像jutoy同学一样想要用透明PNG作为a:hover时的背景图片,那么你需要留意你的代码,需要以”a:hover”来作为选择器. 否则可能会导致无法成功.同时我也更新了demo,请需要的更新查看.接着我们看看正确的代码:
<!–[if IE 6]>
<script type=”text/javascript” src=”js/DD_belatedPNG.js” ></script>
<script type=”text/javascript”>   DD_belatedPNG.fix(‘.trans,.box a:hover’);   </script>
<![endif]–>
七.通过 javascript 和 css 滤镜解决 IE 整站 png 背景透明问题
<script type=”text/javascript” language=”javascript”>
function enablePngImages()
{ var imgArr = document.getElementsByTagName(“IMG”);
for(i=0; i<imgArr.length; i++){
if(imgArr[i].src.toLowerCase().lastIndexOf(“.png”) != -1)
{
imgArr[i].style.filter = “progid:DXImageTransform.Microsoft.AlphaImageLoader(src='” + imgArr[i].src + “‘, sizingMethod=’auto’)”;
imgArr[i].src = “spacer.gif”;
}
if(imgArr[i].currentStyle.backgroundImage.lastIndexOf(“.png”) != -1)
{
var img = imgArr[i].currentStyle.backgroundImage.substring(5,imgArr[i].currentStyle.backgroundImage.length-2);
imgArr[i].style.filter = “progid:DXImageTransform.Microsoft.AlphaImageLoader(src='”+img+”‘, sizingMethod=’crop’)”;
imgArr[i].style.backgroundImage = “url(spacer.gif)”;
}
}
}
function enableBgPngImages(bgElements)
{
for(i=0; i<bgElements.length; i++)
{
if(bgElements[i].currentStyle.backgroundImage.lastIndexOf(“.png”) != -1)
{     //alert(bgElements[i]);
var img = bgElements[i].currentStyle.backgroundImage.substring(5,bgElements[i].currentStyle.backgroundImage.length-2);
bgElements[i].style.filter = “progid:DXImageTransform.Microsoft.AlphaImageLoader(src='”+img+”‘, sizingMethod=’crop’)”;
bgElements[i].style.backgroundImage = “url(spacer.gif)”;
}
}
}
</script>
<img src=”pngpic.png” alt=”” border=”0″ />
<!–[if lt IE 7]>
<script type=’text/javascript’>
var bgElements; enablePngImages(); if(bgElements){    enableBgPngImages(bgElements); }
</script>
<![endif]–>

.pngImg {behavior: url(iepngfix.htc);}
以下片段添加至html文件一.IE6使用gif,其他则使用png来解决PNG背景灰

 

根据转载说个注意事项,DD_belatedPNG.js这个插件和iepng.js新版本的用法是一样的,虽然js代码不一样,但是最后为png生成的代码没看到有什么区别(就连产生的问题都是一样的),所以用哪个都可以。就是关于DD_belatedPNG.js插件,ie6的选择器是必加的,否则该插件可能会对ie8正常的png图片带来不正常的影响。另外在包含大量png的页面中,根据布局的差异,这个插件仍然会产生一些问题,透明是可以透明,但是会改变图片的位置,具体原因没有深研究,目测是因为插件对图片处理后给图片一个绝对定位(position),所以在一些特殊布局下页面就会走形,因此如果一定要用到png图片,一定要多测试。

找到一个IE6不兼容的hack,然后……我疯了

之前总能碰到一种问题,就是你定义好了一些东西的背景,但在IE6最后显示的时候背景不是你设置的那个,左看右看也发现不了这个离奇的现象,今天我终于找到了问题所在。

.button{style}

.button.active{style}

我们有的时候会定义这样的class来解决

<div class=”button active”></div>

这样的需要。

常用的浏览器都没有什么问题,单单这么写IE6也没事,但是你要这么写了

.button{style}

.input{style}

.button.active{style:background:url[1]}

.input.active{style:background:url[2]}

就来事了,IE6会任性地把.button.active的url[1]替换成url[2]。

然后,我就疯了!

.button{style}

.input{style}

.button .active{style:background:url[1]}

.input .active{style:background:url[2]}

这样的写法是不存在问题的。

.button{style}

.input{style}

.button.active{style:background:url[1]}

.input.activea{style:background:url[2]}

这样的写法也是不存在问题的。

然后,然后~我吃药去

被绿色版的IE6玩了

绿色版的ie6我本来也没有寄予厚望,只希望能给我方便做css的hack就好了,结果今天我被IE6和IE7合伙给玩了。
竟然有这样的事情,同样的东西,完全就是css,一点附加内容都没有,在我安装的绿色版上不好用,竟然在别人机器上的IE6有效果,我顿时崩溃,想想原因可能是机器默认安装的IE6可能有其他的支持或者有补丁,即便是如此,这我以后做hack烦恼又多了。
IE7的问题就更离谱,我做一个下拉菜单的效果,试过以后本来在IE6,IE7,FF都很好,可是在IE7做其他测试是猛然发现,在IE7刚打开该页面时很正常,只要你在该页面任何地方点击一次鼠标,我的下拉菜单就真的只有下拉,回不去了,百思不得其解,用了各种山寨方法依然没有完美的解决此问题,难道是IE7对鼠标左键有个默认的onclick事件(后经过测试右键问题同样),无奈只能用其他下拉菜单方法代替。
各种科学不能解释的问题,各种纠结~~
路过的大虾多指点。

碰到ie6中设置display:none后,该层仍有占位问题

对于开始隐藏的层(有display:none;的层)只要加上float:none;就可以解决ie6的占位问题
—————————————————————————————-
制作了一个新页面,尝试完全自己编写tab标签效果。很快就编辑好了,效果非常的赞,在火狐和ie7运行完好,很兴奋,但是,在ie6上我又一次萎靡了~唉~
<div id=”a1″ >图片</div>
<div id=”a2″ style=”display:none”>图片</div>
<div id=”a”>
<div id=”a1″>第一个标签</div>
<div id=”a2″>第二个标签</div>
</div>
用这样的写法不知道为什么在ie6中总是走形,找了半天原因,主要是display:none隐藏层后,虽然看不到了,但还是占了一定的位置。
这让我很头疼,知道原因了,希望只动小部分代码或者css就改变现状,然布局恢复正常,但是都把自己弄睡着了也没有解决=。=
最后,只能退而求其次,用了个比较猥琐的方法,干脆把标签部分和切换层部分用两个大的层分隔开,居然就好用了~不解。
总之碰到这样的问题,你也找不到方法就先用这个方法将就一下,我现在还在寻找最好的方法,如果你有更好的方法,拜托分享一下,不胜感激:)

line-height在IE6中失效的问题与解决方法

做完了一个页面,只对FF和IE7做了兼容,之后在IE6下进行测试,整个内容都缩小了。
经过检查,发现是大多数(强调大多数很重要)的line-height失效,查看一下资料,了解到是因为li中加入图片,会导致line-height失效如
<ul>
<li><a href=”#”>1.css</a><img src=”images/icon9.gif” /></li>
<li><a href=”#”>2.li</a><img src=”images/icon9.gif” /></li>
<li><a href=”#”>3.热门</a><img src=”images/icon9.gif” /></li>
<li><a href=”#”>4.模板</a><img src=”images/icon9.gif” /></li>
<li><a href=”#”>5.百度</a></li>
<li><a href=”#”>6.google</a></li>
<li><a href=”#”>7.搜索</a></li>
<li><a href=”#”>8.解决办法</a></li>
</ul>[来源于http://bbs.blueidea.com/thread-2877695-1-1.html]

解决方法其实很简单,只要不在li中体现出图片的加入就可以,我们可以用很多方法来添加这个图片,虽然都比上述代码麻烦[谁叫ie6流氓呢]。推荐使用把图片单独放在一个li里。

其他方法参考下面:
1.用padding把li撑起来
2.单独把图片写在css中 background

附上其他关于IE6中line-height的失效问题和解决方法:
来源:蹄子流落人间 http://hi.baidu.com/ssl346/blog/item/594eb018bb5069b34aedbcee.html

当在一个容器里文字和img、input、textarea、select、object等元素相连的时候,对这个容器设置的line-height数值会失效; 同时以上元素的行高可能×2:

受影响的浏览器:
Microsoft Internet Explorer 5.01 / Windows
Microsoft Internet Explorer 5.5 / Windows
Microsoft Internet Explorer 6&nbsp;

解决方法:
对和文字相连接的img、input、textarea、select、object等元素加以属性

margin: (所属line-height-自身img,input,select,object高度)/2px 0;
vertical-align:middle

ie6下div最小高度问题

当你去设定一个div高度为小于该div字体时,发现height指定的值失效。

不管你怎么调小高度他还是那么宽~FF就不会出现这样的问题~
ie6 会固执的认为这个层的高度不应该小于字体的行高。所以即使你用 height: 1px; 来定义了一个 div 的高度,实际在ie6下显示的仍然是一个字体大小高度的层。
解决办法:

<div style=”height: 1px; overflow: hidden;”></div>

问题跟进

其实上述的解决办法在设计时看来并不实用,最近看资料又发现既然ie6 会固执的认为这个层的高度不应该小于字体的行高,那么我们可以在标签内部或者css中设置字体大小

font-size:1px;

就可消除默认行高。