若要兼容低版本ie,需要在制作页面时就做向前兼容,最好不要在完成页面之后才开始修改渲染错乱的页面。
-
根据不同的ie版本进行操作(hack)
-
CSS属性:
- ie6:
_
(在属性之前)。 - ie6、ie7:
*
(在属性之前)。 - ie6、ie7、ie8(部分ie9、ie10):
\9
(在属性结束、分号之前)。 - ie8、ie9、ie10、ie11:
\0
(在属性结束、分号之前)。
- ie6:
-
HTML条件注释法:
HTML条件注释法仅支持ie9-。支持的判断:
lt
小于;lte
小于或等于;gt
大于;gte
大于或等于;()
;!
;&
;|
。-
ie9-按条件执行(非ie浏览器和ie10+都当做注释不执行):
<!--[if lt IE 8]> ie6、ie7 <![endif]--> <!--[if IE 8]> ie8 <![endif]--> <!--[if gte IE 8]> ie8、ie9 <![endif]-->
-
非ie浏览器和ie10+都无差别执行,ie9-按条件执行:
<!--[if gte IE 8]><!--> ie8、ie9、ie10+、其他非ie <!--<![endif]--> <!--[if !IE]><!--> ie10+、其他非ie <!--<![endif]-->
-
-
JS判断:
策略:
navigator.userAgent
正则匹配(浏览器嗅探技术)、HTML条件注释法、怪癖检测(try-catch
)。
图片类型选择png-24透明图(png-32)
-
用gulp压缩图片后,图片在ie6~8表现出的颜色会改变,因此不要把背景切入图中,最好用透明的切图。
-
png-24透明图(png-32)和png-24不透明图或png-8压缩后的文件大小相差不大,因此可以都使用png-24透明图切图后再用gulp压缩。
-
png24透明图增加透明区域对文件大小增加很小,因此切图时不必特意限制纯透明区域大小。
-
判断png类型:
file 文件名
file * # 输出: /png-24.png: PNG image data, 宽 x 高, 8-bit/color RGB, non-interlaced /png-32.png: PNG image data, 宽 x 高, 8-bit/color RGBA, non-interlaced /png-8.png: PNG image data, 宽 x 高, 8-bit colormap, non-interlaced
-
-
ie6/7替换写法:
-
float
:float: left/right; _display: inline;
-
display: inline-block
:display: inline-block; *display: inline; *zoom: 1;
-
.clearfix:after {content: ""; display: table; clear: both;}
.clearfix {*zoom: 1;}
-
-
ie6的高度无法小于行高:
_overflow: hidden;
(尤其对于设置背景的节点)
-
兼容至ie6的:
position: absolute;
元素拉升至父容器(position: relative;
)相同高宽:top: 0; bottom: 0; left: 0; right: 0; _height: 100%; _width: 100%;
-
ie6图片无法用png-24透明图(png-32),会把透明部分显示为灰色:
-
gulp压缩图片:
用png-24透明图(png-32)切图,再用gulp压缩。
-
JS方法:内部插件
<!--[if IE 6]> <script src="js/pngfilter.js"></script> <script> DD_belatedPNG.fix('.j-png'); </script> <![endif]-->
插件bug:用div透明背景图覆盖出圆角效果会单边缩短1px,要给背景图左右多出1px背景(JS的bug)。
-
-
ie6不支持
max-height
、min-height
、max-width
、min-width
:- 用
_height/_width
等于固定值适量代替。
- 用
-
ie6字体渲染的高度和其他浏览器不同,
line-height
可能会渲染小一些:- 不处理,否则都要细微调节ie6的行高。
-
ie6的
text-decoration: underline;
的位置与其他主流浏览器不同:- 不处理。
- 用
border-bottom
替代。
-
ie6的
:hover
效果:-
仅支持
<a>
且href
属性要赋值<a href="#"></a>
-
-
ie6查看的网页文件若文件编码不是utf-8会乱码(若出现除了ie6之外都无错误,并且提示的错误位置排查后没有错误的,需要检查编码格式):
- 无论HTML/CSS/JS文件都要手动转化为utf-8。
-
ie6的
<tr>
、<tbody>
不支持border
:border
写在td
或td > *
中。
-
ie6的
width
、height
、line-height
写在<td>
上时,内容超过后设置的限制无效:- 在父级
<table>
上设置table-layout: fixed;
,并在第一个<tr>
的各个子级<td>
或<th>
上设置宽度,就能为整个表固定各项目宽度。 width
、height
、line-height
不设置在<td>
上,设置在<td>
的子级。
- 在父级
-
ie6的
<table>
、<tr>
、<td>
,用JS增加有背景色的class无效:- 要有原始的
background
值,才可以在添加class之后改变background值。
- 要有原始的
-
ie6下
<tr>
没有:hover
效果:- 用JS制作(mouseenter、mouseleave)。
- 不处理。平稳退化(优先完成全部功能,再针对浏览器测试和修复)。
-
ie6浮动元素的中间有注释会导致出现重复字符:
- 删除浮动元素内的注释。
-
ie6不能使用多类选择器(不能连写class或id,e.g.
.a.b
、.a#b
、#a#b
),会自动忽略前面的选择器而仅剩下最后一个class或id。- 用
_
CSS属性hack,对ie6中平稳退化。
- 用
-
ie6不支持
position: fixed;
,需使用JS组建:-
平稳退化。用
position: absolute;
模拟。 -
用JS插件:
内部插件
<script src="js/jquery.js"></script> <script src="js/ks.gototop.js"></script><!-- 依赖jQuery--> <script> ue.gototop({ relative: $('.content-wrapper'), // 相对定位的对象 target: $('#j-sidenav'), // gototop对象,必须设置具体width top/bottom: 270, // 距离顶部或底部的高度 left/right: 25, // 距离相对定位对象的距离 scrollTop: 123, // y轴滚动条滚动到这个位置显示gototop对象,默认:0 fade: false, // 是否开启针对ie6取消渐隐渐现,默认:开启 btn: $('#btn'), // 到达scrollTop位置以内会隐藏 onscroll: function () { // 滚动页面回调函数 } }); </script>
-
-
ie6的
<input>
有很多CSS问题,尽量不要设置复杂的CSS效果在<input>
上:<input>
设display: block;
会跟父级上下有1px间距,用float
解决。
-
ie6/7不支持
:focus
:- 用JS制作,又因为
<input>
问题多,在<input>
外嵌套一层<div>
,对其进行CSS样式修改。 - 平稳退化。
- 用JS制作,又因为
-
ie6/7的子节点脱离文档流后,父节点要截断子节点内容,必须使父节点也脱离文档流:
- 若要用
overflow: hidden;
作用于position: relative/absolute;
的子节点,必须父级也设置position: relative/absolute;
。 - 若要用
overflow: hidden;
作用于float
的子节点,必须父级也浮动
或清除浮动
。
- 若要用
-
若ie6/7下内置滚动条无法滚动,给产生滚动条的容器添加
position: relative;
(应该也是截断文档流问题)。 -
ie6的
z-index
使用:- 节点与要覆盖的节点之间,它们的第一个共同父级内的兄弟节点(2个节点分别的父级)设置
position: relative/absolute;
并且添加z-index
(可以仅设置一方)才能对比覆盖。
- 节点与要覆盖的节点之间,它们的第一个共同父级内的兄弟节点(2个节点分别的父级)设置
-
ie6修改
absolute
的盒子为display: none
会改变父级的高度:- 父节点设定
height
,增加overflow: hidden;
和position: relative;
。 - 先
show()
出替换的内容,再hide()
被替换的内容。
- 父节点设定
-
ie6的
a:hover
之后添加派生选择器CSS效果:e.g.
a:hover .class{}
- 先要设置
a:hover{}
触发:hover
时候的重绘(或重排)效果(可以用zoom: 1;
),再添加a:hover
之后的派生选择器CSS效果,如:显示/隐藏。
ie6用CSS控制子项根据父项
a:hover
的显示隐藏,仅作用于一些文本效果,因此还是要用JS的方式替代此种效果:mouseenter时候添加一个类,类控制CSS来操作子项内容的显示隐藏;mouseleave时候去除此类。 - 先要设置
-
ie6的
:hover
的某些CSS属性值会导致高度变化,其实是触发了haslayout,可以设置CSS属性使:hover
之前就已经haslayout。 -
ie6/7的
text-decoration
会被overflow: hidden;
截断。 -
ie6/7/8不支持CSS3的透明,可以用ie特有的滤镜:
-
整个节点透明:
-
ie6/7
filter: alpha(opacity=50); *zoom: 1;
-
现代浏览器
opacity: 0.5;
-
-
仅仅背景透明,不影响子项内容:
-
ie6/7/8/9
filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr=#80000000, endColorStr=#80000000)\9; *zoom: 1;
startColorStr
是起色点,endColorStr
是终色点(用于渐变色),两个值相同则单色;- 值为16进制数,前两位表示alpha通道值(透明),后六位为RGB值。
-
ie9+
background: rgba(0, 0, 0, .5);
- 使用gif透明图(ie的24位PNG图透明时引起的内存泄漏)。
-
-
-
ie6/7/8/9没有console方法(执行会报错),可用alert替代:
if (typeof console === 'undefined' || typeof console.log === 'undefined') { console = {} console.log = function (msg) { alert(msg) } }
-
ie6下当子节点的宽度超过父节点设置的宽度时,会产生奇怪的样式效果,如:仅设置
padding-top
而会把padding-bottom
也设置一样的值:- 计算好子节点不要超过父节点宽度。
-
ie6下qrcode.js要先把节点展示出来才能够调用方法产生效果,调用完之后再隐藏节点不会有影响(ie6下是用table模拟效果)。
-
ie6下
position: absolute
的文字宽度,若不设置宽度值,其最大宽度等于父级宽度的一半,而在其他主流浏览器下最大宽度等于父级宽度:- 此文字的节点设置
width固定值
。 white-space: nowrap;
强制文本不换行。
- 此文字的节点设置
-
ie6的
负margin
有些情况需要多设置一些,因为可能出现子节点内容超过设定值的情况。 -
ie6的某些兄弟节点间(如:
<img>
和其他inline
或inline-block
节点)因为出现如:overflow: hidden;
造成相对于基线会有对齐问题:vertical: top; margin-top: 某px;
- 只对ie6进行hack操作,
_vertical-align: baseline; _margin-top: 某px;
或_vertical-align: -某px;
。
-
ie6下的
absolute/float
节点在页面重新渲染时,可能出现margin-left
、maring-top
的渲染问题,导致位置发生变化:- 用
padding
、margin-right
、margin-bottom
替代。
- 用
-
ie6下调用的
function
在还未加载到的地方,因为兼容性差,会导致调用不成功的错误,受加载速度影响,现代浏览器不会出现类似情况。 -
ie6下,父级为
float
,其子级要根据内容宽度自适应:子级为display: block;
,若要设置height
就必须要设置width
,否者会导致子级铺满父级。- 子级或子级包裹的内容设置为
display: inline-block; *display: inline; *zoom: 1;
,可以仅设置height
,不用设定width
。
-
ie6下,图片类型直接改变后缀名会导致无法打开;当把
.jpg
的文件后缀保存为.png
在ie6显示时,会阻塞之后所有图片的加载。 -
ie6下因为hover或改变视窗大小或改变DOM位置而导致元素高度变化(甚至移动到看不见地方):
- 可以试着往其父级层层向上增加
zoom: 1;
进行测试,若还是不行则在有高度的地方设置overflow: hidden;
,甚至是最顶端的位置添加才可以修复(有时候基本是向上试错的碰运气)。
- 可以试着往其父级层层向上增加
-
ie6下父级设置
height
、width
,当子级超过限制后,会把父级撑大(没有overflow: hidden;
情况)。 -
若ie6下无法打开https链接:
- 尝试internet选项--高级--使用TLS1.0打钩。
-
ie6/7(/8的低版本或怪异模式)的
document.getElementById
不区分ID大小写,CSS样式会区分大小写。 -
ie6/7的
document.getElementById
会获取name
属性匹配的节点(如:表单节点或其他节点):- 不要让节点的
name
属性与其他节点ID相同。
- 不要让节点的
-
ie6/7/8/9的节点在Flash上可能需要添加
background
才可以点击到。
haslayout是ie6/7的一个私有概念,它决定了元素如何对其内容定位和尺寸计算,以及与其他元素的关系和相互作用。
若一个元素「拥有布局」,它会负责本身及其后代元素的尺寸和定位;若一个元素「没有拥有布局」,它的尺寸和位置由最近的拥有布局的祖先元素控制。
对于早期的ie显示引擎来说,若所有元素都「拥有布局」的话,会导致很大的性能问题。因此ie开发团队决定使用布局概念来减少浏览器的性能开销,即只将布局应用于实际需要的那些元素,所以便出现了「拥有布局」和「没有拥有布局」两种情况。
-
查看haslayout
-
可以用JS读取某DOM对象是否拥有布局(只读):
某DOM.currentStyle.hasLayout;
,返回true:拥有,返回false:不拥有。 -
通过IE Developer Toolbar(打开Show Default Style Values)可以查看ie下HTML元素是否拥有布局(只读):
拥有
haslayout
的元素,属性显示为haslayout = -1
;不拥有的,显示为haslayout = 0
。
-
-
默认拥有布局的元素:
html, body table, tr, th, td img hr input, select, textarea, button iframe, embed, object
-
触发haslayout
haslayout不是CSS属性,我们无法通过CSS显式的设置元素的haslayout,只能通过其他CSS样式触发。
-
ie6/7:
float: left/right;
display: inline-block;
position: absolute;
width: 除了auto之外任何值;
height: 除了auto之外任何值;
zoom: 除了normal之外任何值;
writing-mode: tb-rl;
-
ie7独有
min-height: 任意值;
min-width: 任意值;
max-height: 除了none之外任意值;
max-width: 除了none之外任意值;
overflow: 除了visible之外任意值,仅用于块级元素;
overflow-x: 除了visible之外任意值,仅用于块级元素;
overflow-y: 除了visible之外任意值,仅用于块级元素;
position: fixed;
-
一个「layout元素」只可能是一个默认就拥有 layout 的元素或一个通过设置某些 CSS 属性得到 layout的元素。
ie6/7没有BFC,而有haslayout。
- 尝试在Chrome下重现该bug,若能重现,就先把Chrome里能重现的bug修复。确定Chrome里不重现、但是ie6有问题的,再继续下一步;
- 先尝试高版本ie(如:开发者工具还不错的ie9),可以断点、调用栈分析、控制台。若ie9里没问题,那就继续尝试ie8,一直定位到能重现该问题的最高版本的ie上。若不幸碰上仅出现在ie6的bug,再继续下一步;
- ie6没有太好用的JS调试工具,一般就是二分法+
alert
的土法定位到出错行,加上耐心和时间,还有一点点运气。可以使用抓包工具辅助(Charles);用虚拟机安装windows XP系统并且在ie6上安装IE6DevToolBar。