## 浏览器兼容性问题

浏览器兼容性问题

所谓的浏览器兼容性问题,是指因为不同的浏览器对同一段代码有不同的解析,会造成页面显示效果不统一的情况。在大多数情况下,我们的需求是,无论用户用什么浏览器来查看我们的网站或者登陆我们的系统,都应该是统一的显示效果。所以浏览器的兼容性问题是前端开发人员经常会碰到和必须要解决的问题。

在学习浏览器兼容性之前,我想把前端开发人员划分为两类:

第一类是精确按照设计图开发的前端开发人员,可以说是精确到1px的,他们很容易就会发现设计图的不足,并且在很少的情况下会碰到浏览器的兼容性问题,而这些问题往往都是浏览器的bug,并且他们制作的页面后期易维护,代码重用问题少,可以说是比较牢固放心的代码。

第二类是基本按照设计图来开发的前端开发人员,很多细枝末节差距很大,不如间距,行高,图片位置等等经常会差几px。某种效果的实现也是反复调试得到,具体为什么出现这种效果还模模糊糊,整体布局十分脆弱。稍有改动就乱七八糟。代码为什么这么写还不知所以然。这类开发人员往往经常为兼容性问题所困。修改好了这个浏览器又乱了另一个浏览器。改来改去也毫无头绪。其实他们碰到的兼容性问题大部分不应该归咎于浏览器,而是他们的技术本身了。

文章主要针对的是第一类,严谨型的开发人员,因此这里主要从浏览器解析差异的角度来分析兼容性问题。

问题一:不同浏览器的标签默认的外补丁和内补丁不同

问题症状:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大。

碰到频率:100%

解决方案:可以使用Normalize来清除默认样式,具体可参考文章:来,让我们谈一谈 Normalize.css

也可以使用如下代码:

body,h1,h2,h3,ul,li,input,div,span,a,form …… { margin:0; padding:0; }

备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的CSS文件开头都会用通配符*来设置各个标签的内外补丁是0。

二:块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大

问题症状:常见症状是IE6中后面的一块被顶到下一行

碰到频率:90%(稍微复杂点的页面都会碰到,float布局最常见的浏览器兼容问题)

解决方案:在float的标签样式控制中加入 display:inline;将其转化为行内属性

备注:我们最常用的就是div+CSS布局了,而div就是一个典型的块属性标签,横向布局的时候我们通常都是用div float实现的,横向的间距设置如果用margin实现,这就是一个必然会碰到的兼容性问题。

三:设置较小高度标签(一般小于10px),在IE6,IE7,遨游中高度超出自己设置高度

问题症状:IE6、7和遨游里这个标签的高度不受控制,超出自己设置的高度

碰到频率:60%

解决方案:给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度。

备注:这种情况一般出现在我们设置小圆角背景的标签里。出现这个问题的原因是IE8之前的浏览器都会给标签一个最小默认的行高的高度。即使你的标签是空的,这个标签的高度还是会达到默认的行高。

四:行内属性标签,设置display:block后采用float布局,又有横行的margin的情况,IE6间距bug

问题症状:IE6里的间距比超过设置的间距

碰到几率:20%

解决方案:在display:block;后面加入display:inline;display:table;

备注:行内属性标签,为了设置宽高,我们需要设置display:block;(除了input/img标签比较特殊)。在用float布局并有横向的margin后,在IE6下,他就具有了块属性float后的横向margin的bug。不过因为它本身就是行内属性标签,所以我们再加上display:inline的话,它的高宽就不可设了。这时候我们还需要在display:inline后面加入display:talbe。

五:图片默认有间距

问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,通配符清除间距也不起作用。

碰到几率:20%

解决方案:使用float属性为img布局

备注:因为img标签是行内属性标签,所以只要不超出容器宽度,img标签都会排在一行里,但是部分浏览器的img标签之间会有个间距。去掉这个间距使用float是正道。(也可使用负margin,虽然能解决,但负margin本身就是容易引起浏览器兼容问题的用法,所以尽量不要使用)

六:标签最低高度设置min-height不兼容

问题症状:因为min-height本身就是一个不兼容的CSS属性,所以设置min-height时不能很好的被各个浏览器兼容

碰到几率:5%

解决方案:如果我们要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !important; height:200px; overflow:visible;}

备注:在B/S系统前端开发时,有很多情况下我们有这种需求。当内容小于一个值(如300px)时。容器的高度为300px;当内容高度大于这个值时,容器高度被撑高,而不是出现滚动条。这时候我们就会面临这个兼容性问题。

七:各种特殊样式的兼容,比如透明度、圆角、阴影等。特殊样式每个浏览器的代码区别很大,所以,只能现查资料通过给不同浏览器写不同的代码来解决。

八,清除浮动:

复制代码

  .clearfix::after {
        content: "";
        display: table;
        clear: both;
    }

.clearfix {
    *zoom: 1;
}

九,盒模型

Element {
        box-sizing: border-box;
        /*box-sizing: content-box;*/
    }

/* CSS hack*/

hacker是非常好用的。使用hacker可以把浏览器分为3类:IE6 ;IE7和遨游;其他(IE8 chrome ff safari opera等)

◆IE6认识的hacker 是下划线_ 和星号 *

◆IE7 遨游认识的hacker是星号 *

比如这样一个CSS设置:

div { height: 300px; *height: 200px; _height:100px; }

IE6浏览器在读到height:300px的时候会认为高时300px;继续往下读,他也认识heihgt, 所以当IE6读到height:200px的时候会覆盖掉前一条的相冲突设置,认为高度是200px。继续往下读,IE6还认识_height,所以他又会覆盖掉200px高的设置,把高度设置为100px;

IE7和遨游也是一样的从高度300px的设置往下读。当它们读到*height200px的时候就停下了,因为它们不认识_height。所以它们会把高度解析为200px,剩下的浏览器只认识第一个height:300px;所以他们会把高度解析为300px。因为优先级相同且想冲突的属性设置后一个会覆盖掉前一个,所以书写的次序是很重要的。

做兼容页面的方法是:每写一小段代码(布局中的一行或者一块)我们都要在不同的浏览器中看是否兼容,当然熟练到一定的程度就没这么麻烦了。建议经常会碰到兼容性问题的新手使用。很多兼容性问题都是因为浏览器对标签的默认属性解析不同造成的,只要我们稍加设置都能轻松地解决这些兼容问题。如果我们熟悉标签的默认属性的话,就能很好的理解为什么会出现兼容问题以及怎么去解决这些兼容问题。

10, event.srcElement问题

问题说明:IE下,event对象有srcElement属性,但是没有target属性;Firefox下,even对象有target属性,但是没有srcElement属性。
解决方法:使用srcObj =event.srcElement ?event.srcElement : event.target;

11,dom2级事件

添加事件监听器:addEventListenner(string,fn,boolean);
移除事件监听器:removeEventListenner(string,fn,boolean);
ie兼容性写法
添加事件监听器:attachEvent(string,fn);
移除事件监听器:detachEvent(string,fn,);

12,阻止浏览器的默认行为:

event.preventDefault();
event.returnValue=false;
return false;

13,事件e参数的获取:

document.onkeydown=function(e){
	var evt = e || event;
	var code = evt.which || evt.keyCode;
}

14,阻止事件冒泡的方法:

evt.stopPropagation();

兼容性写法:

evt.cancelBubble=true;

15,srcollTop:可视区域离页面顶部的距离;

scrollTop=document.documentElement.scrollTop||document.body.scrollTop;

16,常见的AJAX请求;

**if(window.XMLHttpRequest){
	var xhr = new XMLHttpRequest();
	}else{
		var xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}**

17,css中透明属性:

IE浏览器写法:filter:alpha(opacity=数值);数值的取值范围1~100(IE8以下);
兼容其他浏览器:opacity:value(value的取值范围0~1);

18,ie6.0横向margin加倍

产生因素:块属性、float、有横向margin。
解决方法:display:inline;

19,ie6.0下默认有行高

解决方法:overflow:hidden;或font-size:0;或line-height:xx px;

20,Ie6下,不识别最大宽、高度和最小宽高度,意即min-width/height和 Max-width/height在ie6中没效果,

解决方法:

(1):.abc{border:1px blue solid;width:200px;height:200px;}
    	html>body .abc{width:auto;height:auto;min-width:200px;min-height:200px;}
(2):.abc{width:200px;height:200px;_width:200px;_height:200px;}

(因为ie6有一个特征,当定义一个高度时,如果内容超过高度,元素会自动调整高度。)

21,Ie6里面:如li设宽、高,并且li里面的标签浮动,那么li之间会有间距

解决方法:li不设宽、高或者li内的标签不浮动

22,li之间有间距

解决方法:li 设置vertical-align:middle;

23,3像素问题:ie6下,当浮动元素与流动元素并列显示时,他们之间会存在三像素问题。
解决方法:用hack技术, 例如:所有浏览器通用 height:100px;
ie6专用_height:100px;
ie7专用*+height:100px;
ie6/ie7共用*height:100px;
24,当定义行内元素为包含框时,且包含框包含的绝对定位元素以百分比为单位进行定位时,会出现混乱。
解决方法:在行内元素里加入{zoom:1;}

25,当多个浮动元素中间夹杂着HTML注释语句时,如果浮动元素宽度为100%,则在下一行多显示一个上一行最后一个字符。

    解决办法:给浮动元素添加display:inline;。

26 两个块元素,竖向的margin值不增加,会重叠,其间距为最大margin值。

27 优先级:被!important 注明的css属性具有最高优先级(.abc{color:red !important;})。但在ie6中!important具有一个bug:在同一组css属性中,!important不起作用。

28 火狐不识别background-position-y 或background-position-x;

29 ie6 不支持 fixed

复制代码
/*对于非IE6可以这样写
*/ #top{ position:fixed; bottom:0; right:20px; }
/*但是IE6是不支持fixed定位的,需要另外重写
*/ #top{ position:fixed; _position:absolute; top:0; right:20px; _bottom:auto; _top:expression(eval(document.documentElement.scrollTop)); }
/使用hack使IE6实现该效果,但这个东东会闪烁,需要以下代码/ *

 html{       background-image:url(about:blank);       background-attachment:fixed;   }   

/使固定在顶部/ #top{ _position:absolute; _bottom:auto; _top:expression(eval(document.documentElement.scrollTop)); }
/固定在底部/ #top{ _position:absolute; _bottom:auto; _top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop)||0)-(parseInt(this.currentStyle.marginBottom)||0))); }
/垂直居中/ #top{ position:fixed; top:50%; margin-top:-50px; _position:absolute; _top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight/2)); }
复制代码

30 解决 ie6 最大、最小宽高 hack方法

复制代码
/* 最小宽度 / .min_width{ min-width:300px; _width:expression(parseInt(this.clientWidth) < 300 ? "300px" : this.clientWidth); }
/
最大宽度 /
.max_width{ max-width:600px; _width:expression(parseInt(this.clientWidth) > 600 ? "600px" : this.clientWidth); }
/
最小高度 /
.min_height{ min-height:200px; _height:expression(parseInt(this.clientHeight) < 200 ? "200px" : this.clientHeight); }
/
最大高度 */ .max_height{ max-height:400px; _height:expression(parseInt(this.clientHeight) > 400 ? "400px" : this.clientHeight); }
复制代码

31 z-index不起作用的 bug

1)ie6下 首先讲讲第一种z-index无论设置多高都不起作用情况。这种情况发生的条件有三个:1、父标签position属性为relative;2、问题标签含有浮动(float)属性。
2)所有浏览器:它只认第一个爸爸
层级的高低不仅要看自己,还要看自己的老爸这个后台是否够硬。用术语具体描述为:
父标签position属性为relative或absolute时,子标签的absolute属性是相对于父标签而言的。而在IE6下,层级的表现有时候不是看子标签的z-index多高,而要看它们的父标签的z-index谁高谁低。

32 ie各个版本hack

复制代码

/类内部hack:/ .header {_width:100px;}
/* IE6专用*/ .header {*+width:100px;}
/* IE7专用*/ .header {*width:100px;}
/* IE6、IE7共用*/ .header {width:100px\0;}
/* IE8、IE9共用*/ .header {width:100px\9;}
/* IE6、IE7、IE8、IE9共用*/ .header {width:330px\9\0;}
/* IE9专用*/ /选择器Hack:/ *html .header{} /*IE6*/ *+html .header{} /IE7/

实战是解决问题的最佳途径,也是遇到问题的唯一途径,大家多多亲自制作才能更快更好的成长,另外多去借鉴别人的经验也是进步的捷径。

你可能感兴趣的:(前端处理浏览器兼容问题)