浏览器的兼容问题
浏览器介绍 :
使用 Trident 内核的浏览器:IE、Maxthon、TT;
使用 Gecko 内核的浏览器:Netcape6 及以上版本、FireFox;
使用 Presto 内核的浏览器:Opera7 及以上版本;
使用 Webkit 内核的浏览器:Safari、Chrome。
不过我们这里谈论浏览器的兼容性,主要谈论主流浏览器,如 IE、FireFox 以及 Chrome,因为它们分别属于不同的浏览器内核,所以以它们为例进行讨论。
有人看到这里可能要问,为什么没有 360 浏览器、QQ 浏览器或 UC 浏览器?事实是国内几乎所有浏览器都是使用的上述浏览器内核,只不过外面换了一层皮肤而已。
兼容性说明 :
对于浏览器的兼容问题,一般分三个方面:
HTML 兼容
CSS 兼容
JavaScript 兼容
大多数我们遇到的兼容性难题是 CSS 某些属性浏览器不支持导致的,这里推荐一个网站 Can I use,可以帮我们检测某个 CSS 属性的浏览 器兼容性情况。
例如查看 flex 的兼容性:https://caniuse.com/#feat=flexbox
从网站上搜索的结果来看,IE 10 开始支持 flexbox 布局,但是需要在属性前面添加前缀 -ms-。
常见问题:
默认样式 : 谈起浏览器兼容性,默认样式可以说是一个最常见的问题。
问题描述 : 我们可以随便写几个 HTML 标签,让后在不同的浏览器中打开,我们会发现它们的边距、边框、大小等都会有不同。
解决方法 :简单粗暴
/* 如果要解决默认边距问题,可以采用如下方法 */
* {
padding: 0;
margin: 0;
}
这种方法有些问题,现在一般不推荐了。一方面 * 导致 CSS 渲染引擎在渲染 CSS 的时候,使用 * 遍历整个 DOM 树,影响性能渲染性能。 另一方面 * 的威力太大,管你是谁,统统重置,把很多没有必要的都重置了。
引入 reset.css :
最先作者是 Eric Meyer,目的是在各个浏览器达到统一的效果。
官网:https://cssreset.com/scripts/eric-meyer-reset-css
引入 normalize.css :
normalize.css 是由 Nicolas Gallagher 和 Jonathan Neal 维护的一个 CSS 重置样式库,Bootstrap 用的就是它。
很多人说 reset.css 太暴力了,normalize.css 相对要温柔一些。normalize.css 修复了不同浏览器常见的不一致,规范化常见的组件风格,
保存有用的默认值。
官网:https://github.com/necolas/normalize.css
IE6 margin bug
问题描述 : 块属性标签 float 后,又有横行的 margin 情况下,在 IE6 显示 margin 比设置的大行内属性标签,设置 display:block; 后采用 float 布局,又有横行的 margin 的情况,IE6 间距 bug。
解决方法 :在 float 的标签样式控制中加入 display:inline; 将其转化为行内属性。在 display:block; 后面加入 display:inline; display:table;,特别注意 inline 加上后宽高就不可设置了,所以我们还需要加上 table。
IE6 和 IE7 默认行高 :
问题描述 :当我们设置较小高度标签(一般小于10px),在 IE6 和 IE7 中高度超出自己设置高度。IE6 和 IE7 都会给标签一个最小默认的行高的高度,即使你的标签是空的,这个标签的高度还是会达到默认的行高。
解决方法 : 给超出高度的标签设置 overflow:hidden; 设置行高 line-height 小于你设置的高度
图片标签默认间距
问题描述 :几个 img 标签放在一起的时候,有些浏览器会有默认的间距,加上问题一中提到的通配符也不起作用。
解决方法 : 因为 img 标签是内联元素,多个 img 标签都会排在一行里,但是部分浏览器的 img 标签之间会有个间距,去掉这个间距使用 float 是正道。
透明度属性 :
问题描述 : opacity 属性 IE9 之前都不支持。
解决方法 : 如果要给标签设置透明属性,需要使用 filter:Alpha(opacity=50);(取值范围 0-100);其他浏览器使用 opacity:value; 即可。
兼容主流浏览器透明属性:
{
filter: alpha(opacity=50);
-moz-opacity: 0.5; /*这个是为了支持一些老版本的Mozilla浏览器*/
-khtml-opacity: 0.5; /*这个为了支持一些老版本的Safari浏览器*/
opacity: 0.5;
}
盒模型 :
问题描述 : 根据 W3C 的规范,元素内容占据的空间是由 width 属性设置的,而内容周围的 padding 和 border 值是另外计算的。不幸的是,IE6 中使用自己的非标准模型。这些浏览器的 width 属性不是内容的宽度,而是内容、内边距和边框的宽度的总和(不包过 外边距)。
解决方法 : CSS 提供了一个属性用来设置元素的盒模型类型。
{
box-sizing: content-box; /*设置标准盒模型*/
box-sizing: border-box; /*IE 盒模型*/
}
其实很好记忆,content 就是内容嘛,说明 width 只是内容的宽度;border 就是边框,说明 width 包含内容、内边距以及边框。
兼容性技巧 :
CSS Hack
主要介绍一下 IE 浏览器的 hack 方法。
IE6 认识 _ 和 *
IE7 认识 *
打个比方,设置这样一个样式:
{
height: 300px;
*height: 200px;
_height: 100px;
}
IE6 三个属性都支持,所以根据就近原则,高度为 100px
IE7 只支持 *,所以高度为 200px
其他浏览器高度为 300px
PostCSS :
-webkit-、-ms-、-moz-这些 CSS 属性前缀相信大家都不会太陌生,某些 CSS 属性,尤其是 CSS3 新增的一些属性,在各大浏览器早期的版本都不能直接支持,必须要加上这些属性前缀。
如果我们写代码时,都手动去添加那岂不累死了。还好前端从不缺少工具,但凡能简化操作的东西,一些高手及爱好者都想到了解决方法,并且提供了开源工具。
PostCSS 就是一个能帮助我们解决前缀问题的 js 工具。
特点 : 增强代码的可读性:利用从 Can I Use 网站获取的数据为 CSS 规则添加特定厂商的前缀。将未来的 CSS 特性带到今天!
终结全局 CSS:就是说你永远不用担心命名太大众化而造成冲突太普通,只要用最有意义的名字就行了。
避免 CSS 代码中的错误。
强大的网格系统:LostGrid 利用 calc() 和你所定义的分割方式来创建网格系统,无需传递大量参数。
使用 : 这里主要讲解一下如何在 webpack 中使用 postcss。
了解详情 :https://webpack.js.org/loaders/postcss-loader/
Polyfill
Polyfill 是一个 js 库,主要抚平不同浏览器之间对 js 实现的差异。比如 html5 的 storage(session 和 local),不同浏览器,不同版本,有些支持,有些不支持。
Polyfill 具体做法典型的是在 IE 浏览器中增加 window.XMLHttpRequest ,内部实现使用 ActiveXObject。
在 GitHub 上 https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills 这里我们可以看到各种新特性的 Polyfill,如果我们用到哪个特性,但是它的支持不是太好,我们就可以从中挑选响应的 js 库来使用。本质
Polyfill 简而言之就是一层包装,通过个浏览器所提供的特有接口来实现同一个功能。