兼容性问题分为两方面,一是浏览器对该特性不支持,二是某些特定条件下触发浏览器BUG。
浏览器特性支持
几个可以查看浏览器支持css特性的网址
- caniuse.com
- codrops CSS Reference
需要兼容哪些浏览器
-
根据用户群体决定
- 面向普通用户:IE8+、Chrome、Firefox
- 企业级产品:IE9+、Chrome、Firefox
-
了解浏览器所占的市场份额
- 百度统计、NetMarketShare
浏览器不支持时怎么办
-
低版本没有这个特性时,表现是否可以接受?
- border-radius: 不支持时,没有圆角,是否还看的过去?
- box-shadows:不支持时,没有阴影,丑不丑?
-
可以使用效果差一点的替代方案么?
- min-height:100vh, 替代成800px
-
可以使用一些替代方案么?
- opacity: 0.5,在IE下使用:filter: alpha(opacity=50)
-
纯css没法子了,用javascript方式让浏览器支持?
- 使用html5shim.js让IE6-8支持新标签
- 使用DD_belatedPNG.js让IE6支持半透明png图片
-
最差情况,跟换实现方案。
让不同浏览器实现不同的布局
@supports
在css3可以使用这个来查询浏览器是否支持某个特性,但是因为@supperts自身在浏览器的兼容性方面还是个问题,所以目前不适用,可能是未来的手段。
浏览器的hack
目前还是采用hack方式较多。
hack原理–层叠和忽略
- 对浏览器无效的属性会被忽略
p {
display: table;
display: flex; /*支持flex时,会覆盖table,不支持则使用table*/
}
- hack原理–条件注释
<!--[if IE 7]>
<p>只有在IE7中才能看到我</p>
<![endif]-->
<!--[if lt IE 8]>
<p>只有在IE8以下才能看到我</p>
<![endif]-->
这是IE中独有的条件注释,只能IE才能识别。可以如下应用:
<!--[if lt IE 7]><html class="ie6"><![endif]-->
<!--[if IE 7]><html class="ie7"><![endif]-->
<!--[if IE 8]><html class="ie8"><![endif]-->
<!--[if IE 9]><html class="ie9"><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!-->
<html class="w3c">
<!--<![endif]-->
通过配合html,在特定版本下给html加载不同的class表示来表名是什么版本的浏览器,后面可以通过iex selector(比如ie6 body {
})来给不同的浏览器做特殊的处理。
浏览器怪癖
主要是利用IE6、7、8上的一些怪异表现来达到某些目的。
/* IE6不支持两个类选择器直接组合,否则是由最后面的选择器生效 */
.unused-class.selector {
/* IE6 only CSS */
}
前面给一个无意义的类名,第二个跟着要应用样式的类,这样这个样式在IE6下会生效,而在高级浏览器中不生效。
.container {
height: 100px;
/* 只有IE6会忽略 */
_height: 200px;
}
在IE6下css属性前面的_会被忽略,被解析成height:200px;而在高版本浏览器中这个属性是无效的。
.container {
height: 100px;
/* 只有IE6和IE7会忽略* */
*height: 200px;
}
注意与上面对比,IE6会忽略_和*,而IE7只会忽略*.
.selector {
color: #fff;
/* IE6-8会忽略属性值后面的\9 */
color: #eee\9;
}
通过IE6-8会忽略\9的特性加上属性覆盖,达到在IE6-8下样式改变的目的。通过上面对比,可知道:
IE8识别\9 ,而不识别*和_。但是IE6和IE7却识别\9.所以一般在IE8中除了问题的样式,在IE6和IE7下也会出问题。
css2选择器兼容性
主要的兼容问题出现在IE6-7上。
IE6不支持多个类直接组合
- p.class-a.class-b解析成p.class-b
- 解决方法:处理好选择器优先级
IE6不支持父子、兄弟选择器
- E > F、E + F和E ~ F选择器无效
- 解决方法:避免使用,换成后代选择器或其他
IE6-7不支持伪元素
- 不支持:before和:after
IE6不支持某些伪类
- 不能在非链接的元素上使用:hover、:active
- 解决方法:使用a嵌套需要hover的元素即可
IE6-7不支持:focus伪类
- 使用javascript解决
IE6不支持:first-child伪类
- 解决方法:给第一个元素添加first类。
综上,对于CSS2的选择器来说,只有在IE6上支持性较差,而在IE7+就可以大胆使用CSS2的选择器了。
CSS3选择器
- 在IE9+,才兼容大部分的CSS3选择器
- 移动端支持绝大部分CSS3选择器,所以大胆使用
一些兼容性问题的解决
IE6不支持min/max-width/height
- min-height解决办法:
div {
min-height: 500px;
/* IE6中height表现与min-height一致 */
_height: 500px;
}
- min-width解决办法
<div class="container">
<!--[if IE 6]><div class="struct"></div><![endif]-->
</div>
<style>
.container {
min-width: 500px;
}
/* IE6 */
.container .struct {
height: 1px;
width: 500px;
}
</style>
- max-width/height解决办法
- 只能使用javascript解决
IE6-7块级元素不支持inline-block
- 行级元素支持,而块级元素不支持display: inline-block.
- 解决办法:
.selector {
display: inline-block;
*display: inline;
*zoom:1;
}
IE6-7不支持display:table
- 使用float或inline-block替代table布局。
- 不推荐使用inline-block做大块的布局。
IE8不支持
-
background-size
- 在响应式布局时,如果浏览器支持该属性,则可以通过设置该属性让背景图随着容器宽度的变化而变化。
- 在IE6-8下,是不支持这属性的,当然在这些低版本的浏览器当中就要做个降级处理,不实现响应式布局。
-
border-radius
-
border-shadow
-
opacity
- filter: alpha(opacity=50)
-
rgba、hsl、hsla
- 一般情况下使用相近的不透明颜色来代替
- Alpha可以通过设置额外元素,并设置透明度来实现
-
rem/vh/vw/calc
- 降级为固定宽度
IE9不支持
- transition和animation
- 使用javascript解决
浏览器前缀
- Chrome/Safari/Opera: -webkit-
- Microsoft: -ms-
- Mozilla: -moz-
使用autoprefixer css online来给代码自动添加前缀。
浏览器BUG
IE6下半透明png显示不正确
- DD_belatedPNG.js
- filter
IE6浮动元素双边距bug
- 浮动元素与浮动同方向的边距加倍
.selector {
float: left;
/* IE6下为20px */
margin-left: 10px;
}
- 解决方法:
.selector {
float: left;
margin-left: 10px;
_display: inline;
}
hasLayout
这是IE里特有的属性,当一个元素有layout时,他就有自己的宽度和高度,没有layout时,就按照内容来计算宽度和高度。加zoom:1就可以让他具有layout。
控制IE模式(IE<=10)
- Doctype有无控制是否进入怪异模式
- meta标签控制进入哪种文档模式
/* 使用IE7模式渲染 */
<meta http-equiv="X-UA-Compatible" content="IE=7">
/* 使用最新引擎 */
<meta http-equiv="X-UA-Compatible" content="IE=edge">
兼容性测试
- 虚拟机
- BrowerStack
polyfill
- 使用代码来让浏览器实现它尚未支持的特性
- CSS Polyfill
- selectivizr
- CSS3 PIE
- box-sizing-polyfill
- flexbility
- cssSandpaper