目前, 最为流行的浏览器共有五个: 分别是 ie,Edge 浏览器(属于微软), 火狐, 谷歌(chrome)Safari 和 Opera 五大浏览器.
Trident 内核: IE ,360,, 猎豹, 百度;
Gecko 内核: 火狐 ----------->这个浏览器内核是开源的浏览器内核, 插件非常多,-------------->缺点: 打开速度慢(加载 flash 插件)<----- 额外介绍 ----->.
Presto 内核: Opera7 及以上版本
webkit: 遨游, 苹果 ,symbian;Safari,Chrome
Bink:Chrome(28 及往后版本),Opera(15 及往后版本)和 Yandex 浏览器, 大部分国产浏览器最新版本都采用 Blink;
对浏览器兼容问题, 一般分, html,Javascript 兼容, CSS 兼容. 其中 html 相关问题比较容易处理, 无非是高版本浏览器用了低版本浏览器无法识别的元素, 导致其不能解析, 所以平时注意一点就是.
一, 兼容问题集合
问题一: 不同浏览器的标签默认的外补丁和内补丁不同
问题症状: 随便写几个标签, 不加样式控制的情况下, 各自的 margin 和 padding 差异较大.
碰到频率: 100%
解决方案: css 里
*{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 标签比较特殊). 在用 float 布局并有横向的 margin 后, 在 ie6 下, 他就具有了块属性 float 后的横向 margin 的 bug. 不过因为它本身就是行内属性标签, 所以我们再加上 display:inline 的话, 它的高宽就不可设了. 这时候我们还需要在 display:inline 后面加入 display:talbe.
问题五: 图片默认有间距
问题症状: 几个 img 标签放在一起的时候, 有些浏览器会有默认的间距, 加上问题一中提到的通配符也不起作用.
碰到几率: 20%
解决方案: 使用 float 属性为 img 布局
备注: 因为 img 标签是行内属性标签, 所以只要不超出容器宽度, img 标签都会排在一行里, 但是部分浏览器的 img 标签之间会有个间距. 去掉这个间距使用 float 是正道
问题六: 标签最低高度设置 min-height 不兼容
问题症状: 因为 min-height 本身就是一个不兼容的 css 属性, 所以设置 min-height 时不能很好的被各个浏览器兼容
碰到几率: 5%
解决方案: 如果我们要设置一个标签的最小高度 200px, 需要进行的设置为:
{min-height:200px; height:auto !important; height:200px; overflow:visible;}
备注: 在 B/S 系统前端开发时, 有很多情况下我们有这种需求. 当内容小于一个值 (如 300px) 时. 容器的高度为 300px; 当内容高度大于这个值时, 容器高度被撑高, 而不是出现滚动条. 这时候我们就会面临这个兼容性问题.
问题七: 透明度的兼容 css 设置
方法是: 每写一小段代码 (布局中的一行或者一块) 我们都要在不同的浏览器中看是否兼容, 当然熟练到一定的程度就没这么麻烦了. 建议经常会碰到兼容性问题的新手使用. 很多兼容性问题都是因为浏览器对标签的默认属性解析不同造成的, 只要我们稍加设置都能轻松地解决这些兼容问题. 如果我们熟悉标签的默认属性的话, 就能很好的理解为什么会出现兼容问题以及怎么去解决这些兼容问题.
二, 技巧
技巧一: css hack
使用 hacker 我可以把浏览器分为 3 类: ie6 ;ie7 和遨游; 其他(ie8 chrome ff safari opera 等)
ie6 认识的 hacker 是下划线_ 和星号 *
ie7 遨游认识的 hacker 是星号 * (包括上面问题 6 中的 !important 也算是 hack 的一种. 不过实用性较小.)
比如这样一个 css 设置 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.
因为优先级相同且相冲突的属性设置后一个会覆盖掉前一个, 所以书写的次序是很重要的.
- /* 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 识别 */
越少的浮动, 就会越少的代码, 会有更灵活的页面, 会有扩展性更强的页面. 这不多说, 归结为到一定水平了, 浮动会用的较少. 另外, 您也会避免使用浮动 + margin 的用法. 所以, 越后来越不易遇到这种 bug.
技巧二: padding,marign,height,width
注意是技巧, 不是方法: 写好标准头 http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "> http://www.w3.org/1999/xhtml"> 尽量用 padding, 慎用 margin,height 尽量补上 100%, 父级 height 有定值子级 height 不用 100%, 子级全为浮动时底部补个空 clear:both 的 div 宽尽量用 margin, 慎用 padding,width 算准实际要的减去 padding
技巧三: 显示类(display:block,inline)
- display:block,inline 两个元素
- display:block; // 可以为内嵌元素模拟为块元素
- display:inline; // 实现同一行排列的的效果
- display:table; //for FF, 模拟 table 的效果
display:block 块元素, 元素的特点是: 总是在新行上开始; 高度, 行高以及顶和底边距都可控制; 宽度缺省是它的容器的 100%, 除非设定一个宽度
display:inline 就是将元素显示为行内元素, 元素的特点是: 和其他元素都在一行上; 高, 行高及顶和底边距不可改变; 宽度就是它的文字或图片的宽度, 不可改变. span,a,label,input,img,strong 和 em 是 inline 元素的例子
技巧四: 怎样使一个 div 层居中于浏览器中?
- 1)
- <style type="text/css">
- <!-- div {
- position:absolute;
- top:50%;
- left:50%;
- margin:-100px 0 0 -100px;
- width:200px;
- height:200px;
- border:1px solid red; } -->
- </style>
2)div 里的内容, IE 默认为居中, 而 FF 默认为左对齐, 可以尝试增加代码 margin: 0 auto;
技巧五: float 的 div 闭合; 清除浮动; 自适应高度
例如:
<div id="floatA"><div id="floatB"><div id="NOTfloatC">
这里的 NOTfloatC 并不希望继续平移, 而是希望往下排.(其中 floatA,floatB 的属性已经设置为 float:left;)
这段代码在 IE 中毫无问题, 问题出在 FF. 原因是 NOTfloatC 并非 float 标签, 必须将 float 标签闭合. 在
<divclass="floatB"><div class="NOTfloatC">
之间加上
<div class="clear">
这个 div 一定要注意位置, 而且必须与两个具有 float 属性的 div 同级, 之间不能存在嵌套关系, 否则会产生异常. 并且将 clear 这种样式定义为为如下即可:.clear{clear:both;}
作为外部 wrapper 的 div 不要定死高度, 为了让高度能自适应, 要在 wrapper 里面加上 overflow:hidden; 当包含 float 的 box 的时候, 高度自适应在 IE 下无效, 这时候应该触发 IE 的 layout 私有属性 (万恶的 IE 啊!) 用 zoom:1; 可以做到, 这样就达到了兼容.
例如某一个 wrapper 如下定义:
.colwrapper{overflow:hidden; zoom:1; margin:5px auto;}
对于排版, 我们用得最多的 css 描述可能就是 float:left. 有的时候我们需要在 n 栏的 float div 后面做一个统一的背景, 譬如:
- <div id="page">
- <div id="left"></div>
- <div id="center"></div>
- <div id="right"></div>
- </div>
比如我们要将 page 的背景设置成蓝色, 以达到所有三栏的背景颜色是蓝色的目的, 但是我们会发现随着 left centerright 的向下拉长, 而 page 居然保存高度不变, 问题来了, 原因在于 page 不是 float 属性, 而我们的 page 由于要居中, 不能设置成 float, 所以我们应该这样解决:
- <div id="page">
- <div id="bg" style="float:left;width:100%">
- <div id="left"></div>
- <div id="center"></div>
- <div id="right"></div>
- </div>
- </div>
再嵌入一个 float left 而宽度是 100% 的 DIV 解决之.
万能 float 闭合(非常重要!)
关于 clear float 的原理可参见 [How To ClearFloats Without Structural Markup], 将以下代码加入 Global CSS 中, 给需要闭合的 div 加上 class="clearfix" 即可, 屡试不爽.
- /* Clear Fix */
- .clearfix:after { content:"."; display:block; height:0; clear:both;visibility:hidden; }
- .clearfix { display:inline-block; }
- /* Hide from IE Mac */
- .clearfix {display:block;}
- /* End hide from IE Mac */
- /* end of clearfix */
或者这样设置:.hackbox{display:table; // 将对象作为块元素级的表格显示}
技巧六: div 嵌套时 y 轴上 padding 和 marign 的问题
FF 里 y 轴上 子 div 到 父 div 的距离为 父 padding + 子 marign
IE 里 y 轴上 子 div 到 父 div 的距离为 父 padding 和 子 marign 里大的一个
FF 里 y 轴上 父 padding=0 且 border=0 时, 子 div 到 父 div 的距离为 0, 子 marign 作用到 父 div 外面
一, 360 显示不正确
Web 页面在 360 等浏览器上, 显示不正确. 但是在 Firefox,chrome 和 IE8 + 以上的浏览器上, 都是显示正常的.
问题的分析
1. 检查了一些 Javascript 框架, 标准的 jquery 类库 1.x 系列, 确认其工作正常, 问题不是在于 Javascript 方面.
2. 排查掉 HTML 标签内容的显示 问题.
3. 怀疑是 CSS 在不同浏览器下的兼容性问题, 见过排查, 没有发现问题.
4. 排查 360 浏览器, 发现其在当前页面的显示中, 默认使用了 IE7 的渲染引擎. 同时, 在 IE7 的环境下, 重现了类似情况.
5. 本质上, 这个显示问题是页面在 IE7 下面的兼容性显示问题.
通过实验, 发现只有在 IE7 内核下面才存在兼容性显示问题
发现问题的产生是浏览器 "兼容模式" 惹的祸
关于 360 浏览器或搜狗浏览器的分析:
对于此类浏览器, 有时候号称双核或者 N 核的高速浏览器, 其本质上就是本地 IE 浏览器的壳子, 外加 Chrome 抑或 Firefox 的内核, 大部分情况下都是 WebKit 系列内核.
那么, 此类浏览器依据什么信息, 来判断页面的渲染模式呢? 答案就是可以指令运行当前页面的浏览器使用何种渲染引擎的声明.
<meta http-equiv="X-UA-Compatible" content="IE=8">
这里, 就是指令浏览器至少要使用 IE8 以上的渲染引擎来, 渲染页面, 从而规避掉 IE7 下的问题.
于是在 header 中加入以下代码, 我认为真正起作用的是第二行代码, 但为了保险起见, 两行我都选用
- <meta name="renderer" content="webkit">
- <meta http-equiv="X-UA-Compatible" content="IE=8">
于是页面即使在兼容模式下也恢复正常显示. 但还有一个问题, 显然这样在使用原生的 IE 浏览器浏览时也会选用 ie8 内核, 我还需要修改一下.
于是, 将代码中的 8 改为 11,
<meta http-equiv="X-UA-Compatible" content="IE=11">
, 问题解决.
关于 Doctype.
- <!DOCTYPE> 声明必须是 HTML 文档的第一行, 位于 <html> 标签之前.
- <!DOCTYPE> 声明不是 HTML 标签; 它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令.
在 HTML 4.01 中,<!DOCTYPE> 声明引用 DTD, 因为 HTML 4.01 基于 SGML.DTD 规定了标记语言的规则, 这样浏览器才能正确地呈现内容.
分析: doctype 所要解决的就是使用何种 HTML 的语法解析器和渲染器. 比如特定 HTML 标签的使用, 则依赖于 HTML Doctype 的使用.
二, innerText 和 textContent
nnerText 谷歌, 火狐和 IE8 都支持
低版本 的火狐不支持 innerText
textContent 在 IE8 中的结果是 undefined;
textContent 在谷歌和火狐中支持;
这些内容是必须知道的, 也是以后解决兼容性问题的引子或者思路, 同时也是基础.
在解决浏览器兼容性的问题上面, 首先, 可以通过获取浏览器的版本来判断这个浏览器是不是支持这个属性, 但是这种办法非常的麻烦.
具体做法是: 我要在一系列的信息中找到这个浏览器版本里面的具体是什么样的, 然后用正则表达式去匹配, 然后确定这个浏览器里面具体用的什么东西. 这就是整个的内容, 所以, 相当的麻烦.
当然, 获取浏览器版本的代码很简单, 就一句话, 一行代码, 但是仅仅是为了判断这个浏览器是不是支持这个属性 , 是不是放在这里好像有点儿大材小用了. 因此, 就直接判断这个浏览器里面是不是支持这个属性就可以了.
为了解决这个不兼容的问题, 我们可以编辑以下代码来解决上述问题:
- // 任意元素都可以设置成文本内容 ---------- 因此把 "任意" 元素当成对象 (element) 传递到函数中
- //element---->任意元素
- //text--->任意文本内容
- function setInnerText(element,text) {
- if(typeof (element.textContent)=='undefined'){// 是 IE8 浏览器
- element.innerText=text;
- }else{
- // 浏览器支持 textContent 这个属性
- element.textContent=text;
- }
- }
- // 获取任意元素中的文本内容
- function getInnerText(element) {
- if(typeof (element.textContent)=="undefined"){
- // 如果浏览器不支持 textContext 这个属性则返回 innerText 的值
- return element.innerText;
- }else{
- // 如果浏览器支持 textContext 属性, 则直接返回该属性的值
- return element.textContent;
- }
- }
上述代码就可以解决 innnerText 和 textContent 在各个浏览器之间不兼容的问题(上述代码目前只在谷歌, 火狐, IE8 版本上面测试, 以后还会在其他的浏览器的不同版本上面测试, 测试结果还会不断的更新, 尽请期待).
上面介绍的内容只阐述部分属性在各个浏览器上面的差异, 当然, 还有其他的兼容问题存在, 他们分别是:
(1)获取某个元素中的第一个子元素
(2)获取某个元素中的最后一个子元素
(3)获取某个元素的前一个兄弟元素
(4)获取某个元素的后一个兄弟元素
下面, 我分别给出了相应的兼容性问题解决办法代码:
- // 获取某个元素中的第一个子元素
- function getFirstElement(element) {
- if(element.firstElementChild){
- // 如果浏览器支持这个属性就直接返回第一个子元素
- return element.firstElementChild;
- }else{
- // 如果浏览器不支持这个 firstElementChild 属性, 先获取传入进来的父级元素中的第一个子节点
- var node=element.firstChild;// 先获取这个节点
- while (node&&node.nodeType!=1){// 判断节点存在并且不是标签
- node=node.nextSibling;// 继续找当前节点的下一个节点
- }
- return node;
- }
- }
- // 下面这连个属性在各个不同的浏览器中显示的方式有所不同
- //my$("uu").firstChild
- //my$("uu").firstElementChild
- // 获取某个元素中的最后一个子元素
- function getLastElement(element) {
- if(element.lastElementChild){
- return element.lastElementChild;
- }else{
- // 获取当前元素的最后一个子节点
- var node=element.lastChild;
- while (node&&node.nodeType!=1){
- node=node.previousSibling;
- }
- return node;
- }
- }
- // 获取某个元素的前一个兄弟元素
- function getPreviousElement(element) {
- if(element.previousElementSibling){
- return element.previousElementSibling
- }else{
- var node=element.previousSibling;
- while (node&&node.nodeType!=1){
- node=node.previousSibling;
- }
- return node;
- }
- }
- // 获取某个元素的后一个兄弟元素
- function getNextElement(element) {
- if(element.nextElementSibling){
- return element.nextElementSibling
- }else{
- var node=element.nextSibling;
- while (node&&node.nodeType!=1){
- node=node.nextSibling;
- }
- return node;
- }
- }
来源: http://www.bubuko.com/infodetail-2659515.html