前端兼容性问题

  • 对于前端来说兼容性问题就是浏览器的兼容问题
  • 有不同浏览器的兼容问题
  • 也有相同浏览器的不同版本的兼容问题
  • 一共分为两大类的兼容问题:
    • 和页面渲染相关的 HTML 和 CSS 兼容问题
    • 和 JS 引擎相关的 JS 解析 : DOM 和 BOM

HTML 兼容

  • 这个解决起来最简单
    1
    2
    3
    <!--[if lte IE 9]>
    <script src="./lib/html5shiv.min.js"></script>
    <![endif]-->

CSS 兼容

  • 100% 出现的一个浏览器兼容问题

    不同浏览器下的标签默认的内边距和外边距
    解决办法:{margin: 0; padding: 0; }

  • 为什么不能定义1px左右的div容器?

    在 IE6 上存在这个问题,高版本则不会出现
    IE6 下这个问题是因为默认行高造成的,解决的方法也有很多
    例如:overflow:hidden | zoom:0.08 | line-height:1px

  • 在处理响应式布局中有些老版本的浏览器不支持媒介查询

    到 IE7 仍然支持 媒介查询
    引入 respond.js 即可解决

  • 块级标签float后,又有横向的margin情况下,在IE6显示margin比设置的大

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

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

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

  • 设置较小高度标签(一般小于10px),在 IE6 中高度超出自己设置高度

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

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

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

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

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

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

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

  • 图片默认有间距

    问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,添加 margin 和 padding 也不起作用。

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

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

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

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

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

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

  • 浏览器兼容问题七:透明度的兼容CSS设置

    / CSS hack/

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

移动端
  • 字体兼容
    • 各个手机系统有自己的默认字体,且都不支持微软雅黑
    • 如无特殊需求,手机端无需定义中文字体,使用系统默认
    • 英文字体和数字字体可使用 Helvetica ,三种系统都支持

CSS hack

什么是CSS hack

由于不同厂商的流览器或同一浏览器的不同版本(如IE6-IE11,Firefox/Safari/Opera/Chrome等)
对CSS的支持、解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果
这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本的浏览器写特定的CSS样式
我们把这个针对不同的浏览器/不同版本写相应的CSS code的过程,叫做CSS hack

CSS hack的原理

由于不同的浏览器和浏览器各版本对CSS的支持及解析结果不一样
以及CSS优先级对浏览器展现效果的影响,我们可以据此针对不同的浏览器情景来应用不同的CSS

CSS hack分类

CSS Hack大致有3种表现形式
CSS属性前缀法、选择器前缀法 以及 IE条件注释法 (即HTML头部引用if IE)Hack
实际项目中 CSS Hack 大部分是针对IE浏览器不同版本之间的表现差异而引入的

  • 属性前缀法(即类内部Hack):例如 IE6能识别下划线_和星号*,IE7能识别星号*,但不能识别下划线_,IE6~IE10都认识\9,但firefox前述三个都不能认识。

  • 选择器前缀法(即选择器Hack):例如 IE6能识别 *html .class{},IE7能识别*+html .class{}或者*:first-child+html .class{}

  • IE条件注释法(即HTML条件注释Hack):

  • 针对所有IE(注:IE10+已经不再支持条件注释): <!--[if IE]>IE浏览器显示的内容 <![endif]-->
  • 针对IE6及以下版本: <!--[if lt IE 6]>只在IE6-显示的内容 <![endif]-->
  • 这类Hack不仅对CSS生效,对写在判断语句里面的所有代码都会生效

  • CSS hack方式一:条件注释法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!--[if IE]>
    这段文字只在IE浏览器显示
    <![endif]-->


    <!--[if IE 6]>
    这段文字只在IE6浏览器显示
    <![endif]-->


    <!--[if gte IE 6]>
    这段文字只在IE6以上(包括)版本IE浏览器显示
    <![endif]-->


    <!--[if ! IE 8]>
    这段文字在非IE8浏览器显示
    <![endif]-->


    <!--[if !IE]>
    这段文字只在非IE浏览器显示
    <![endif]-->

  • CSS hack方式二:类内属性前缀法
    属性前缀法是在CSS样式属性名前加上一些只有特定浏览器才能识别的hack前缀,以达到预期的页面展现效果。
    IE浏览器各版本 CSS hack 对照表

hack 写法 IE6(S) IE6(Q) IE7(S) IE7(Q) IE8(S) IE8(Q) IE9(S) IE9(Q) IE10(S) IE10(Q)
* *color Y Y Y Y N Y N Y N Y
+ +color Y Y Y Y N Y N Y N Y
- -color Y Y N N N N N N N N
_ _color Y Y N Y N Y N Y N N
# #color Y Y Y Y N Y N Y N Y
\0 color:red\0 N N N N Y N Y N Y N
\9\0 color:red\9\0 N N N N N N Y N Y N
!important color:blue !important;color:green; N N Y N Y N Y N Y Y
  • S :标准模式
  • Q :怪异模式

  • 说明:在标准模式中

    • - 减号是IE6专有的hack
    • \9 IE6/IE7/IE8/IE9/IE10都生效
    • \0 IE8/IE9/IE10都生效,是IE8/9/10的hack
    • \9\0 只对IE9/IE10生效,是IE9/10的hack
  • CSS hack方式三:选择器前缀法
    选择器前缀法是针对一些页面表现不一致或者需要特殊对待的浏览器
    在CSS选择器前加上一些只有某些特定浏览器才能识别的前缀进行hack

html 前缀只对IE6生效
+html +前缀只对IE7生效
@media screen\9{…}只对IE6/7生效
@media \0screen {body { background: red; }}只对IE8有效
@media \0screen\,screen\9{body { background: blue; }}只对IE6/7/8有效
@media screen\0 {body { background: green; }} 只对IE8/9/10有效
@media screen and (min-width:0\0) {body { background: gray; }} 只对IE9/10有效
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {body { background: orange; }} 只对IE10有效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/* CSS属性级Hack */ 

color:red; /* 所有浏览器可识别*/

_color:red; /* 仅IE6 识别 */

*color:red; /* IE6、IE7 识别 */

+color:red; /* IE6、IE7 识别 */

*+color:red; /* IE6、IE7 识别 */

[color:red; /* IE6、IE7 识别 */

color:red\9; /* IE6、IE7、IE8、IE9 识别 */

color:red\0; /* IE8、IE9 识别*/

color:red\9\0; /* 仅IE9识别 */

color:red \0; /* 仅IE9识别 */

color:red!important; /* IE6 不识别!important 有危险*/

/* CSS选择符级Hack */

*html #demo { color:red;} /* 仅IE6 识别 */

*+html #demo { color:red;} /* 仅IE7 识别 */

body:nth-of-type(1) #demo { color:red;} /* IE9+、FF3.5+、Chrome、Safari、Opera 可以识别 */

head:first-child+body #demo { color:red; } /* IE7+、FF、Chrome、Safari、Opera 可以识别 */

:root #demo { color:red\9; } : /* 仅IE9识别 */

/* IE条件注释Hack */

<!--[if IE 6]>此处内容只有IE6.0可见<![endif]-->

<!--[if IE 7]>此处内容只有IE7.0可见<![endif]-->

原文出处

  • 双边距bug 由 float 引起的, 使用 display 解决
  • img 3 像素问题, 由 float 引起的,使用 display: block; 可以解决
  • hover 点击后失效问题,使用正确的书写顺序:link visited hover active
  • IE 中 z-index 问题,给父级添加position: relative
  • png 透明,使用 JS 来改
  • min-height 最小高度,!important 解决
  • IE6 不支持 png 透明背景,解决办法: IE6 下使用 png8 图片
  • select 在 IE6 下会遮盖,使用 iframe 嵌套
  • 为什么没有办法定义 1px 左右的宽度容器( IE6 默认的行高造成的,使用overflow:hidden; zoom: 0.08; line-height: 1px;)
  • IE5-8不支持opacity,解决办法:

    1
    2
    3
    4
    5
    .opacity {
    opacity: 0.4;
    filter: alpha(opacity=60); /* for IE5-7 */
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; /* forIE8*/
    }
  • LI中内容超过长度后以省略号显示
    此技巧适用与IE、Opera、safari、chrom浏览器,FF暂不支持。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <style type="text/css">
    li {
    width:200px;
    white-space:nowrap;
    text-overflow:ellipsis;
    -o-text-overflow:ellipsis;
    overflow: hidden;
    }
    </style>

DOM 兼容

DOM 操作相关兼容
  • getElementsByClassName
  • getElementsByClassName 兼容到 IE7
  • 火狐低版本 不支持 innerText ,支持 innerContent
  • 自定义属性问题
    问题说明:IE下,可以使用获取常规属性的方法来获取自定义属性
    也可以使用 getAttribute() 获取自定义属性
    Firefox下,只能使用 getAttribute() 获取自定义属性
    解决方法:统一通过 getAttribute() 获取自定义属性

  • input.type属性问题
    问题说明:IE下input.type属性为只读;但是Firefox下input.type属性为读写。
    解决办法:不修改input.type属性
    如果必须要修改,可以先隐藏原来的input
    然后在同样的位置再插入一个新的input元素

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

事件相关兼容
  • 添加事件的兼容性处理
    onclick 是一个通用的添加事件的方法
    现代事件 IE9 以前: dom.attachEvent('onclick', fn);
    标准浏览器: dom.addEventListener('click', fn);

  • event.x与event.y问题
    说明:IE下,event对象有x,y属性,但是没有pageX,pageY属性
    Firefox下,event对象有pageX,pageY属性,但是没有x,y属性

BOM 兼容

  • window.location.href问题
    说明:IE或者Firefox2.0.x下,可以使用 window.location 或 window.location.href;
    Firefox1.5.x下,只能使用 window.location.
    解决方法:使用 window.location 来代替 window.location.href

JS 中 IE678 兼容处理一览表

- 标准浏览器 IE678
获取样式值 getComputedStyle(dom, null)[attr] dom.currentStylt[attr]
获取卷去的值 window.pageYOffset document.documentElement.scrollTop
获取屏幕尺寸 window.innerHeight document.documentElement.clientWidth
添加事件 addEventListener attachEvent
事件对象 e window.event
获取事件目标元素 target srcElement
阻止事件冒泡 e.stopPropagation() window.event.canceBubble = true;
阻止默认行为 e.preventDefault() window.event.returnValue = false;
文章目录
  1. 1. 前端兼容性问题
    1. 1.1. HTML 兼容
    2. 1.2. CSS 兼容
      1. 1.2.0.0.1. 移动端
  2. 1.2.1. CSS hack
    1. 1.2.1.0.1. 什么是CSS hack
    2. 1.2.1.0.2. CSS hack的原理
    3. 1.2.1.0.3. CSS hack分类
  • 1.3. DOM 兼容
    1. 1.3.0.0.1. DOM 操作相关兼容
    2. 1.3.0.0.2. 事件相关兼容
  • 1.4. BOM 兼容