做者: xcntime 发表于 2010-08-11 10:49 原文连接 阅读: 0 评论: 0javascript
去年就想将IE的bug系统地整理下,但一直都忙于工做、学习没有完成,看到这篇E文后,我绝不犹豫的放下了手中的工做将之翻译出来。
因为是第一次译文,因此错误在所不免,欢迎你们批评指正。css
原文:Ultimate IE6 Cheatsheet: How To Fix 25+ Internet Explorer 6 Bugshtml
翻译:http://www.vfresh.org/w3c/727(译文对原文进行了补充)前端
对IE6最好的策略就是不去兼容它。java
好吧,我知道你的难处,你不得不去兼容IE6这个狗血的浏览器,所以不得不在兼容IE6上花费不少时间。对此,我很有同感,来让我来帮助你吧。jquery
我不会象许多文章那样让你去抵制IE6,这并不会帮助到你(无可奈何时)去兼容IE6;由于IE6依旧占有必定的市场份额,你没法放弃IE6。本文将帮助你来解决这个难题。web
我查阅过不少资料来摘录这些解决方案(有些是我本身提供的),如今我作成手册提供给你们搞定IE6这个家伙。我尽量的提供了最优解决方案而不是一些hacks,而且提供了一些相关的资料。若是你发现有更好的方法或者本文有错误,请联系我。canvas
在讨论IE6的BUG及如何修复以前,有必要先讲一些策略去避免这些恼人的问题——正所谓防患于未然 。api
兼容IE6的第一步就是单独对IE进行兼容,你针对IE6所写的代码只影响IE6。浏览器
解决IE6布局方面的BUG很是的恼人!特别是在实现一个精美的设计稿时。
ie6有着一些行为方面的BUG,究其缘由是IE6版本太老了,不能无缺地支持CSS2更不支持CSS3,并且微软执拗的使用了其私有方法。
IE6有着数不尽的JavaScript bug,这里我不会讲解每个IE6下JavaScript的bug,只摘取其中几个广泛的问题来讨论。
在讨论IE6的BUG及如何修复以前,有必要讲叙一些策略去避免这些恼人的问题——正所谓防患于未然 。
据Market Share统计,目前(2009年8月)IE6 的市场占有率为25.25%,可是其余地方的统计明显要低,为18.1%;尽管统计结果不一样,但都呈现出了降低的趋势(翻译此文时,淘宝的IE6用户已从70%跌破至69%)。可是最重要的,仍是你本身网站的统计数据。若是你对你的网站进行了流量分析,那么IE6的占有率是否值得你去针对IE6进行开发?这须要你本身去权衡。
若是你网站绝大部分访问者不使用IE6而且不付费给你,那么你没必要特地区针对IE6作兼容,从而节省时间、精力及资金。
在作设计的同时考虑代码的实现,能够避免一些布局上的问题。再复杂的设计稿也能用简洁的代码实现,若是你使用了过于繁冗的标签,那么你须要从新修缮设计稿。
若是你有丰富的开发经历,攻克过不少种布局难题,记录下你的解决方案,在之后碰到相同问题时能够提升开发效率。
使用一个错误的文档声明会触发quirks mode(怪异模式),正确的文档声明能够保证你的页面在全部浏览器下保持一致的效果。使用其中的一个文档申明:HTML 5
, HTML 4.01 Strict
, HTML 4.01 Frameset
, HTML 4.01 Transitional
, XHTML 1.0 Strict
, XHTML 1.0 Frameset
, XHTML 1.0 Transitional
, or XHTML 1.1
<!DOCTYPE HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
我曾据说过有些人认为校验代码没有任何实用价值,但我不这么认为。校验仅仅只需花费一点点时间,并且将受益于全部浏览器而非仅仅IE6;验证确保了向后兼容而且易于维护。至少也得验证XHTML!惟一能够忽略验证的状况是在你打算使用CSS3时。
在写代码的过程当中,一开始在标准浏览器中测试(如 Firefox, Opera, Chrome等),而后再去测试非标准浏览器(如IE6/IE7),由于这些标准浏览器都遵循w3c标准,大多的处理方式都相同。你能够分开来单独去兼容“特别”的IE浏览器,这样作能规范你的代码,你将会所以拥有扎实的基础;并且若是你再也不须要兼容这些非标准浏览器,你能够一次性删除这些修复兼容性代码。
渐进加强(Progressive Enhancement)是为了确保没有页面特效后基本功能也是可用的。简单来说,渐进加强是指在确保页面在禁用JavaScript后能正常运做后,再对页面添加各类特效(JavaScript动画、Ajax异步等等)。咱们一样能够运用“渐进加强”原则来使用CSS3(或者一些CSS2)、HTML5以及其余IE6所不支持的web规范。
某些状况下,是没法让全部用户在任何浏览器下都彻底如出一辙,特别是那些使用IE6的用户。运用渐进加强策略,能够保证让那些用户至少使用到你网站(或网络应用)的基本功能。
每一个浏览器都有各自不一样的预设样式,在你的样式表以前使用预设样式(CSS Reset)能够避免在以后编写冗长的浏览器兼容样式。在网上有不少CSS Reset可供参考。
body,div,ul,ol,li,h1,h2,h3,h4,h5,h6,form,fieldset,input,textarea,p,th,td {margin:0;padding:0;}
若是你的网站使用了较多的JavaScript特效,建议使用JavaScript框架。大部分的js框架都兼容了包括IE6在内的各类浏览器。可选的框架有不少,但通常能用一种框架实现的效果必定能够用另一种框架实现,因此你能够根据我的喜爱来选择合适的框架。
如下是一些经常使用的JavaScript框架:
强烈推荐实用MooTools,但若是你是入门者,仍是建议使用jQuery。
如今有一些JavaScript来使IE模拟标准浏览器,若是你有较高比例的用户使用IE6而且开启了JavaScript,能够考虑使用Dean Edwards的IE7或者相似的脚本。
译者注:不建议使用这些脚本,由于这些“模拟”的实现每每会消耗大量的资源,IE原本就够烂了。
在IE下调试页面很麻烦,Firefox下的扩展程序Firebug和Web Developer Toolbar都是很好用的工具,若是你想在IE或其余浏览器上使用firebug,能够用Firebug Lite。
在IE下有两种最好的调试方法:IE Collection和IETester,而且都是免费的(虽然有一点点缺陷)。IETester的开发者也提供了DebugBar这款IE插件免费供我的使用,但商业用户只可试用60天。
兼容IE6的第一步就是单独对IE进行兼容,你针对IE6所写的代码只影响IE6;有几种方法能够区分开IE6:IE特有条件注释、CSS选择器、JavaScript,咱们将逐一讨论。
微软给IE添加了条件注释以区分不一样版本,任何东西均可以塞进条件注释里:标签、JavaScript、js文件、css、内联样式。可使用条件注释来针对某一个IE浏览器版原本编写代码。
规则以下:(译注:可参考IE 特有注释(hack))
<p>这段文字会在全部浏览器显示p><!--[if lte IE 6]><p>这段文字仅显示在 IE6及IE6如下版本。p><p>This message will only appear in versions of Internet Explorer less than or equal to version 6.p><![endif]--> <!--[if gte IE 6]><p>这段文字仅显示在 IE6及IE6以上版本。p><p>This message will only appear in versions of Internet Explorer greater than or equal to version 6.p><![endif]--> <!--[if gt IE 6]><p>这段文字仅显示在 IE6以上版本(不包含IE6)。p><p>This message will only appear in versions of Internet Explorer greater than version 6.p><![endif]--> <!--[if IE 5.5]><p>这段文字仅显示在 IE5.5。p><p>This message will only appear in Internet Explorer 5.5.p><![endif]--> <!--在 IE6及IE6如下版本中加载css--><!--[if lte IE 6]><link type="text/css" rel="stylesheet" href="css/ie6.css" /><![endif]--> <p>这段文字会在全部浏览器显示p>
使用条件注释加载css的好处是这些样式是独立于其余css文件的,所以不会在编写兼容代码时弄得一团糟;并且当IE6的市场份额下降到不须要兼容时,能够快速的清理掉。
使用条件注释的惟一缺点是在IE浏览器下会增长额外的HTTP请求数,因此须要权衡是否这样作。但我不建议使用条件注释加载外部js文件,由于js文件会形成阻滞,在js未加载完以前其他文件都不会被加载;对于js请使用JavaScript程序来区分浏览器而非条件注释。
若是你不打算使用条件注释,CSS选择器是另一个区分开IE6的办法,IE6不支持子选择器;先针对IE6使用常规申明CSS选择器,而后再用子选择器针对IE7+及其余浏览器。
示例:
<style type="text/css" >/* IE6 专用 */.content {color:red;}/* 其余浏览器 */div>p .content {color:blue;}style><div><p class="header">Some Header Text Herep>div>
这个方法的缺点是容易把样式表弄得一团糟,因此必定要写好注释说明。
在示例中,针对IE6写的样式在其余浏览器中也会执行,但(标准浏览器中)以后的子选择器覆盖了以前的申明,而IE6不支持子选择器因此忽略了它。
若是你想要使用JavaScript区分开IE6,请看示例:
//原生JavaScriptif(typeof document.body.style.maxHeight === "undefined") {alert('IE6 Detected');} //MooTools(框架)if (Browser.Engine.trident4) {alert('IE6 Detected');} //jQuery(框架)if (($.browser.msie) && ($.browser.version == "6.0")){alert('IE6 Detected');}
有不少JavaScript解决方案来修复IE6使用PNG-24图片,但除了Twin Helix’s IE5.5+ PNG Alpha Fix都不支持CSS sprites。
另一个办法是使用IE特有的滤镜,可阅读Aaron Baxter的博客。或译者的《ie5+ PNG Fix》
能够详细阅读CSS 圆角菜单。
若是你给连接、按钮用CSS sprites做为背景,你可能会发如今IE6下会有背景图闪烁的现象。形成这个的缘由是因为IE6没有将背景图缓存,每次触发hover的时候都会从新加载,能够用JavaScript设置IE6缓存这些图片:
document.execCommand("BackgroundImageCache",false,true);
解决IE6布局方面的BUG很是的恼人!特别是在实现一个精美的设计稿时。
许多IE6下的Bug及渲染问题均可以归于微软的私有概念hasLayout
。简要的说,在给元素定义具体的尺寸(如height
或width
)就会触发hasLayout
,在IE6下缺失或触发hasLayout会致使一些bug。
若是怪异模式(quirks mode)在IE6中启用,IE6将会使用微软旧版的盒模型:width是元素的实际宽度,内容宽度 = width – (margin-left + margin-right + padding-left + padding-right + border-left-width + border-right-width)。最好的办法是申明正确的文档类型以免触发怪异模式,或者避免给有border
或padding
的元素定义width
属性。固然你也能够考虑使用条件注释。
IE6 不支持min-height
属性,但它却认为height
就是最小高度。感谢Dustin Diaz提供了一个很好的方法:使用!important
,ie6会忽视它但其他浏览器不会。
注:IE6在同一个声明语句中(即一个综括号{}
)的属性定义,后面的老是会覆盖前面的,因此下例中后面的height覆盖掉了前面定义的important height
/* 全部浏览器 */#container {min-height:200px; height:auto !important; height:200px;}
另外一个方法是使用CSS 选择器:
/* 仅IE6 */#container {min-height:200px; height:200px;} /* 其余浏览器 */html>body #container { height:auto;}
很是遗憾,在IE6下实现max-height
只能使用IE特有滤镜,或者可使用JavaScript实现。我我的更建议使用JavaScript来解决,由于IE滤镜会消耗大量资源甚至会使浏览器崩溃,并且禁用JavaScript后这两种方法都没法生效。
//直接使用ID来改变元素的最大高度var container = document.getElementById('container');container.style.height = (container.scrollHeight > 199) ? "200px" : "auto"; //写成函数来运行function setMaxHeight(elementId, height){var container = document.getElementById(elementId);container.style.height = (container.scrollHeight > (height - 1)) ? height + "px" : "auto";} //函数示例setMaxHeight('container1', 200);setMaxHeight('container2', 500);
在IE6下,若是要给元素定义100%高度,必需要明肯定义它的父级元素的高度,若是你须要给元素定义满屏的高度,就得先给html
和body
定义height:100%;
。
/* 给child元素定义100%高度(IE6)*/#parent {height:500px;}#child {height:100%;} /* 定义满屏高度(IE6)*/html, body {height:100%;}#fullLength {height:100%;}
同max-height
和max-width
同样,IE6也不支持min-width
。有2个方法实现最小宽度,使用额外的标签、使用JavaScript。
//直接使用ID来改变元素的最小宽度var container = document.getElementById('container');container.style.width = (container.clientWidth < width) ? "500px" : "auto"; //写成函数来运行function setMinWidth(elementId, width){var container = document.getElementById(elementId);container.style.width = (container.clientWidth < width) ? width + "px" : "auto";} //函数示例setMinWidth('container1', 200);setMinWidth('container2', 500);
只能使用JavaScript。
//直接使用ID来改变元素的最大宽度