(一)前言

浏览器兼容性问题一直都让我很头疼,网上大神们给出的解决方法也是五花八门,向后或向前兼容的说法都有,所以自己整理一下,如果有不恰当的欢迎指正!

(二)CSS兼容问题的原因

我觉得要解决问题,就要先找出问题的根源,所以先研究通常出现的CSS兼容问题的原因有哪些……

1、浏览器内核的差异

浏览器的内核是分为两个部分的,一是渲染引擎,另一个是JS引擎。现在JS引擎比较独立,内核更加倾向于说渲染引擎。由于渲染引擎不同,渲染的方式不同,所以出现了css和html等表现差异,例如像素的错位、颜色表示方式、浮动和定位性能等等。

以下是转载的关于桌面浏览器市场份额的数据。

css 除了 px rem em 还有什么兼容适配的 前端css兼容问题_CSS


css 除了 px rem em 还有什么兼容适配的 前端css兼容问题_css_02

(2016年8月份全球桌面浏览器市场份额——数据来自蓝点网)

从上图可以看出,主流浏览器主要有以下几种(也对应我们平常说的几大浏览器内核):

  1. chrome浏览器(Blink内核-源自webkit内核(区别))
  2. IE浏览器(Trident内核)
  3. Firefox火狐浏览器(Gecko内核=Mozilla内核)
  4. Microsoft Edge内置浏览器(渲染引擎是EdegHTMLEdgeHTML,JS引擎是查克拉(Chakra)都是新的)
  5. Safari浏览器(Webkit内核)
  6. Opera浏览器(Presto内核)

内核知识参考:各种浏览器内核的区别 内核知识参考:五大流浏览器内核及其代表

除了最新的Microsoft Edge浏览器的最新内核之外,以上其他内核都是我们常见的浏览器内核,也是平常在解决兼容性问题之前要了解和熟悉的。

但是还没完……

接下来又要“谈IE色变”了……

众所周知,IE多个版本的兼容性问题一直都是前端开发中令人烦躁的问题,对于这个问题的解决方法是最容易找到,但也最不好整理的。想知道为什么IE这么烦?点这里看知乎回答。下面先整理一下IE的几个版本对应的window版本(好让你心里有点数):

css 除了 px rem em 还有什么兼容适配的 前端css兼容问题_内核_03

由于国内用户的windows操作系统版本大多老旧,而IE浏览器又是windows系统自带的默认浏览器,且其自动更新功能不佳(甚至并没有),所以导致大部分用户的IE浏览器停留在低版本、版本层次不齐的状态。结果就是苦了我们做开发的了。

题外话:在这里想安利一下今天看到的一个观点: 一位知乎答友说的“一个策略”:把浏览器分两类,一类是历史遗留浏览器,一类是现代浏览器,然后根据这个分类开发两个版本的网站,然后自己定义那些浏览器是历史遗留版本,凡是历史遗留版本浏览器,统统使用历史遗留版界面,然后通过通告栏(信息通知系统)明确告知本版本有些功能不能使用,尽快转移到现代浏览器上。然后现代浏览器的网站版本,功能全开,提供最好的用户体验。

2、用户客户端的环境不同

客户端环境,我的理解是屏幕尺寸和分辨率的不同,这也会引起所谓的“浏览器兼容性问题”,这就涉及到对于屏幕尺寸、颜色显示的兼容。 这个后面再另开文章详细分析,本篇主要解决由于浏览器内核出现在兼容性问题。

(三)css兼容开发

参考:知乎专栏-也谈兼容性——通用hack方法/CSS兼容方案/js兼容方案全推送 参考:常见浏览器兼容性问题与解决方案 参考:主流浏览器css兼容问题的总结


(1)CSShack方式1:条件注释法

通过IE浏览器中的专有条件注释可有针对性的进行相关属性的定义。 条件注释只能用于IE5+。 条件注释只能在IE下使用,因此我们可以通过条件注释来为IE添加特别的指令。 通俗点,条件注释就是一些if判断,但这些判断不是在脚本里执行的,而是直接在html代码里执行的。 比如:

<!--[if IE]>

     这里是正常的html代码

<![endif]-->

1,条件注释的基本结构和HTML的注释( )是一样的。因此IE以外的浏览器将会把它们看作是普通的注释而完全忽略它们。

2,IE将会根据if条件来判断是否如解析普通的页面内容一样解析条件注释里的内容。

3,条件注释使用的是HTML的注释结构,因此他们只能使用在HTML文件里,而不能在CSS文件中使用。 可使用如下代码检测当前IE浏览器的版本,并针对不同版本加载对应的css

(注意:在非IE浏览器中是看不到效果的)

<link type="text/css" rel="stylesheet" href="css.css" />
<!--[if IE 7]>
    <link type="text/css" rel="stylesheet" href="ie7.css" />
<![endif]-->
<!--[if IE 6]>
    <link type="text/css" rel="stylesheet" href="ie6.css" />
<![endif]-->

注意:默认的CSS样式应该位于HTML文档的首行,进行条件注释判断的所有内容必须位于该默认样式之后。

下面是IE注释语句中的常见语法:

css 除了 px rem em 还有什么兼容适配的 前端css兼容问题_CSS_04


(2)CSShack方式2:类内属性前缀法


IE浏览器 hack写法一览(类内属性前缀法)

css 除了 px rem em 还有什么兼容适配的 前端css兼容问题_CSS_05

说明:在标准模式中 “-″减号是IE6专有的hack “\9″ IE6/IE7/IE8/IE9/IE10都生效 “\0″ IE8/IE9/IE10都生效,是IE8/9/10的hack “\9\0″ 只对IE9/IE10生效,是IE9/10的hack

(3)选择器前缀法

选择器前缀法是针对一些页面表现不一致或者需要特殊对待的浏览器,在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有效等等

(4)!important关键字

!important 在css中是声明拥有最高优先级,也就是说,不管css的其他优先级,只要!important出现,他的优先级就最高!遨游1.6及更低版本、IE6及更低版本浏览器不能识别它。尽管这个!important 很实用,但是非到必要的时刻,不要使用它! 实例:

<style type="test.css">
.test{
    color: green;
    color: black !important;//←他赢了,.test是黑色,连行内样式也被打败!
}
</style>
.
.
.
<div class="test" style="color:red">>我终究还是属于!important</div>

所以如果你使用某种css插件、想要改改某个元素的样式,却发现连行内样式也不管用的时候,就要看看是不是被设置!important了。

(4)其他常见CSS兼容注意事项

a标签CSS顺序

很多新人在写a标签的样式,会疑惑为什么写的样式没有效果,其实只是写的样式被覆盖了,正确的a标签顺序应该:

  • link
  • visited
  • hover
  • active

24位的png图片

IE6不支持透明咋办?使用png透明图片呗,但是需要注意的是24位的PNG图片在IE6是不支持的,解决方案有两种:

1、使用8位的PNG图片 2、为IE6准备一套特殊的图片

图片透明度

opacity: 0.8; //通用
filter: alpha(opacity=80); //IE
filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=80); //IE6的写法

IE6双边距

行内属性设置了块级属性(display: block;)后,会产生双倍边距。 解决方案是在添加一个 display: inline; 或者 display: table;

双倍margin

浮动元素设置了margin在IE6下会产生双倍margin。 只要给浮动元素设置 display: inline;就可以了。或者说使用IE6的hack:_margin;

min-height的兼容写法

.divBox{
  min-height:200px;
  height:auto !important;
  height:200px;
  overflow:visible;
}

IE6最小宽度写法

.divBox{
  min-width:600px;
    _width: expression(document.body.clientWidth < 600? "600px":"auto");
}

盒模型差异

IE盒模型:margin 、 content(包含border、padding) W3C盒模型: margin 、border、 padding、 content

CSS3中的box-sizing的属性就是为了这两种模式,border-box(IE盒明星)和content-box(W3C)

img标签-图片存在边距

使用 vertical-align 属性可以清楚这种边距

顺便说下a标签同样会存在边距,具体的解决方法可以看看去除inline-block元素间间距的N种方法;

IE6 高度无法小于10px

添加overflow的属性 设置font-size的属性为高度的大小

float的块元素在IE9及以下出现双倍margin

解决方法:display:inline; //使浮动被忽略

.divBox{
  float:left;
  width:100px;
  margin:0 0 0 100px;            //这种情况之下IE会产生200px的距离
  display:inline;                //使浮动忽略
}

总结

以上兼容问题和解决可能不尽详细,有待补充。