根据我的实践经验。如果你在写HTML/CSS时候是按照W3C推荐的方式写的,那么基本的浏览器兼容问题都是可以避免的。
这里主要考虑是的ie8-,个人目测Ie9+的渲染效果已经跟的上主流了。
测试ie兼容最好要在win7+上测试,因为winXP最高支持IE8。
这里贴出百度统计的浏览器市场份额:
PC端:
再给一张国外的
测试网址http://gs.statcounter.com/
目测谷歌是主流啊,变化平稳。排在第二的是IE8,Ie6的地位还是有的,不过占有率不高了,如果不是做学校政府机关方面的基本可以忽略不计了。
个人建议你的项目考虑是浏览器:谷歌,ie8+,Firefox,Safari,opera,360浏览器,搜狗。这些浏览器最好都用真实设备实测。
OK,现在我们就来写点小代码避免浏览器不兼容的问题吧。
首先要确保你的HTML页面开始有DOCTYPE声明。DOCTYPE告知浏览器使用什么样的HTML或XHTML规范来解析HTML文档。DOCTYPE还会对浏览器的渲染模式产生影响,不同的渲染模式会影响到浏览器对CSS甚至JS的解析。尤其是IE系列的浏览器,由DOCTYPE所决定的HTML页面渲染可以差很多,可以把你的页面弄个面目全非。
看下面的声明,这是我以前常用的DOCTYPE声明
<span style="font-family:SimSun;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"></span>
参考:
http://w3help.org/zh-cn/kb/001
http://w3help.org/zh-cn/casestudies/002
http://www.w3cschool.cn/tag_doctype.html
上面推荐使用(项目中都用这声明了)
<span style="font-family:SimSun;"><!DOCTYPE html></span>
在我以前的项目里。后端的同志们老是觉得这个声明没啥用,总自作主张的把它删掉,或者乱用这个声明,因为即使你删除或者乱用都不会报错的,但是偏偏在某个浏览器下就出现这样那样的问题,找你过去看了半天,原来他把DOCTYPE声明给删除了,我真心想说靠。这是一个小细节,希望童鞋们都注意了。
解决方案:
使用头部开始
<!DOCTYPE html>
IE8发布的时候,相对于IE6/7已经做出了相当大的改进,向w3c漫进很大一步。IE8发布的时候,当时很多的网站都是基于Ie6/7来做处理的,如果瞬间改为ie8渲染,有点不科学。所以ie8就加入了“兼容模式”功能,这样就可以再Ie8浏览器中
使用Ie6/7的内核渲染页面。但是对于现在的我们来说,我们是不需要这样的。所以我们可以使用meta标签来强制的让Ie8使用最新的内核渲染页面。
<span style="font-family:SimSun;"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"></span>
国内的很多浏览器都是双核浏览器,比如306浏览器,搜狗,它们是怎么决定用哪个内核来渲染页面的呢?
这里引用了360浏览器帮助的一段文字来回答:
“由于众所周知的情况,国内的主流浏览器都是双核浏览器:基于Webkit内核用于常用网站的高速浏览。基于IE的内核用于兼容网银、旧版网站。以360的几款浏览器为例,我们优先通过Webkit内核渲染主流的网站,只有小量的网站通过IE内核渲染,以保证页面兼容。在过去很长一段时间里,我们主要的控制手段是一个几百k大小网址库,一个通过长期人工运营收集的网址库。
尽管我们努力通过用户反馈、代码标签智能判断技术提高浏览器的自动切核准确率。但是在很多情况下,我们仍然无法达到百份百正确。因此,我们新增加了一个控制手段:内核控制Meta标签。只要你在自己的网站里增加一个Meta标签,告诉360浏览器这个网址应该用哪个内核渲染,哪么360浏览器就会在读取到这个标签后,立即切换对应的内核。并将这个行为应用于这个二级域名下所有网址。
目前该功能已经在所有的360安全浏览器实现。我们也建议其它浏览器厂商一起支持这个实现。让这个控制标签成为行业标准。”
360浏览器建议我们采用webkit
<span style="font-family:SimSun;"><meta name="renderer" content="webkit"></span>
解决方案:
在任何页面的头部加上
<!-- 指定以最新的IE版本模式来显示网页 --> <meta http-equiv="X-UA-Compatible" content="IE=edge,<span style="font-family: SimSun;">chrome=1</span> " /> <!-- 360浏览器相关设置:http://se.360.cn/v6/help/meta.html --> <!-- 针对360浏览器的内核调用,强制调用极速模式 --> <meta name="renderer" content="webkit" /> <!-- 针对360浏览器强制调用IE标准模式 --> <!--[if lt IE 10]> <meta name="renderer" content="ie-stand" /> <![endif]--> <!--[if !IE]> <meta name="renderer" content="ie-stand" /> <!<![endif]-->
标准做法
<span style="font-family:SimSun;">// 单行注释 <!-- this is a comment --> // 多行注释 <!-- and so is this one, which occupies more than one line --></span>
<span style="font-family:SimSun;">// 此处的注释,在各浏览器下,都能被作为注释标签正常识别 <! -- this is a comment --> </span>
<span style="font-family:SimSun;"><!-- 这里是---注释内容 --></span>
按标准推荐的方法写注释标签,如:
<!-- //此处 "<!" 和 "--" 之间尽量不要有空格。
这里是注释内容,应避免在注释内容中出现两个或以上的“-”字符。
--> //此处 "--" 和 ">" 之间避免有空格。
根据规范,服务器应该提供给用户端文档的字符编码信息,最直接的方式为通过http协议”Content-Type“头字段的”charset“将文档字符编码告诉用户端。
如:http头声明了字符编码为UTF-8。
<span style="font-family:SimSun;"><pre name="code" class="javascript">Content-Type<span style="font-family: Arial, Helvetica, sans-serif;">="text/html;charset=UTF-8"</span></span>处于某种情况无法访问服务器时,html文档可以包含有关文档的字符编码的明确信息,meta元素可以用来为用户端提供这些信息,
<span style="font-family:SimSun;"><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></span>
优先级:
各浏览器中运行效果如下:
IE6 IE7 IE8 Firefox | Chrome Safari | Opera |
---|---|---|
字符编码 --- GB2312 | ×Ö·û±àÂë --- ISO-8859-1 | 字符编码 --- GBK |
解决方案:
首先,对于动态页面必须确保 HTTP "Content-Type" 头字段的 "charset" 参数与页面自身编码相符,且务必在页面的 META 元素中也声明相符的字符编码信息。对于静态页面,必须保证页面中 META 元素声明中 "http-equiv" 为 "Content-Type" 对应的值中的 "charset" 的值与页面自身编码相符。
其次,在设置字符编码别名时,最好使用最通用的、各浏览器均可识别的编码别名。
规范中提到,DTD的前面或后面允许出现空白符(空格符,换行符,制表符和注释)。但是如果在DTD之前加入注释或其他内容,在某些浏览中改DTD可能会无效。
一个 HTML 文档的 DTD 前边如果出现其他字符,在各浏览器中的处理情况是不一致的。
具体差异请参考下表:
如果 DTD 之前出现 | 浏览器是否能识别该 DTD | ||||||
---|---|---|---|---|---|---|---|
IE6 | IE7 | IE8 | Firefox | Chrome | Safari | Opera | |
空格符 换行符 制表符 | 可以识别 | 可以识别 | 可以识别 | 可以识别 | 可以识别 | 可以识别 | 可以识别 |
注释1 | 不能识别 | 不能识别 | 不能识别 | 可以识别 | 可以识别 | 可以识别 | 可以识别 |
XML 声明2 | 不能识别 | 可以识别 | 可以识别 | 可以识别 | 可以识别 | 可以识别 | 可以识别 |
其他不包含“<”的字符3 | 不能识别 | 不能识别 | 不能识别 | 可以识别 | 不能识别 | 不能识别 | 不能识别 |
其他包含“<”的字符4 | 不能识别 | 不能识别 | 不能识别 | 不能识别 | 不能识别 | 不能识别 | 不能识别 |
【注】
1. 即HTML注释,如 <!-- comment -->。
2. 类似 <?xml version="1.0" encoding="utf-8"?> 的 XML 声明。
3. 即不是空格符、换行符、制表符,也不是注释、XML 声明的任何其他字符串,但不能包含“<”字符。
4. 即不是空格符、换行符、制表符,也不是注释、XML 声明的任何其他字符串,其中包含“<”字符。
通过以上对比可以看出,要保证 DTD 在所有浏览器中都能正常识别,DTD 之前只能出现空格符、换行符和制表符。
声明 DTD 时,确保 DTD 之前没有其他字符,即便有,也只能是空格符、换行符和制表符。
如将 DTD 放在 HTML 文档的第一行。
这个问题是 WebKit 引擎在处理紧密相连的内联元素时存在自动换行计算上的 Bug 。
针对此问题,我们使用以下测试样例来说明,分析以下代码:
<span style="font-family:SimSun;"><body> <a>[a]</a><span>[span]</span><strong>[strong]</strong><i>[i]</i><b>[b]</b><big>[big]</big><small>[small]</small><em>[em]</em><dfn>[dfn]</dfn><code>[code]</code><samp>[samp]</samp><kbd>[kbd]</kbd><var>[var]</var><cite>[cite]</cite><abbr>[abbr]</abbr><acronym>[acronym]</acronym><sub>[sub]</sub><sup>[sup]</sup><bdo>[bdo]</bdo> </body></span>
减小浏览器窗口尺寸后,在各浏览器中表现如下:
Chrome Safari | IE6 IE7 IE8 Firefox Opera |
---|---|
通过上图比较可以发现,在非 WebKit 引擎的浏览器内,不管元素排列如何紧密,都可以随着布局大小自动换行显示; 而在 WebKit 引擎的浏览器中所有紧密相连的内联元素都在同一行显示,并且与文档模式无关。
避免出现紧密连接的内联元素标签,可以在每个标记之间加入空格或者换行符来避免这个问题。
W3C 规定 "ASCII 空格" 、 "ASCII 制表符" 、 "ASCII 换行符" 等属于空白符(white space),对于多个连续的空白符,浏览器将对他们进行合并。
BR 元素会在当前行强制插入一个换行符,这个换行符也是空白符的一种。
Chrome 和 Safari 中 BR 元素前的空白符不会被忽略,多余的空白符将被压缩为一个空白符并渲染到 BR 元素之前的行中。这个现象可能造成在 Chrome 和 Safari 中出现多余空白符占有位置,从而影响到容器的宽度或者行内元素的对齐效果。
<div style="zoom:1; overflow:hidden; margin-top:10px;">
<p style="text-align:right;">
<span style="background:#ddd;">A</span> <br /><span style="background:#eee;">B</span>
</p>
<p style="text-align:center;">
<span style="background:#ddd;">A</span> <br /><span style="background:#eee;">B</span>
</p>
<p style="text-align:left;">
<span style="background:#ddd;">A</span> <br /><span style="background:#eee;">B</span>
</p>
</div>
Chrome Safari 没有忽略 BR 元素之前的空白符。而 其他浏览器 则将其忽略。
仅当容器的宽度不够容纳子元素时,Chrome Safari 才会忽略 BR 元素之前的空白符。
删除 BR 元素之前多余的空白符。
object元素定义了一个嵌入的对象,通常情况下,IE系列通过ActiveX插件使用object元素引入flash,而其他浏览器则通过相应的插件使用embed元素。这就造成了各浏览器中插入flash的方式的差异。
若仅仅使用 OBJECT 元素设置了 classid 属性引入 Flash,则可能造成在某些浏览器中 Flash 无法被引入。而若嵌套的 OBJECT 和 EMBED 元素参数不统一,也可能造成引入的 Flash 在各浏览器中出现差异。
通常我们会使用如结构代码引入flash:
<object width="200" height="200" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#4,0,0,0">
<param name="src" value="clock.swf" />
<param name="quality" value="high" />
<embed src="clock.swf" type="application/x-shockwave-flash" width="200" height="200" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
</object>
将embed元素嵌套在object元素中,ie就会优先使用object元素而忽略embed元素,在其他浏览中则优先使用embed元素而忽略object元素。这样做虽然可以保证在所有浏览器中均能正确加载flash,但若object元素和embed元素的参数设定不统一,则导致flash在各个浏览器中显示效果不一致,甚至无法正常加载。
官方给出如下html中引用flash的情况。请参考 Adobe 官方知识库文档:OBJECT and EMBED syntax | Flash 与 Flash OBJECT and EMBED tag attributes中的内容。
<span style="font-family:SimSun;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400" id="movie_name" align="middle"> <param name="movie" value="movie_name.swf"/> <!--[if !IE]>--> <object type="application/x-shockwave-flash" data="movie_name.swf" width="550" height="400"> <param name="movie" value="movie_name.swf"/> <!--<![endif]--> <a href="http://www.adobe.com/go/getflash"> <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player"/> </a> <!--[if !IE]>--> </object> <!--<![endif]--> </object></span>
<div style="border:5px solid black; padding:5px; float:left;">
<embed src="clock.swf" type="application/x-shockwave-flash" width="200" height="200" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
</div>
直接使用 EMBED 元素,所有浏览器均支持。
在规范中该属性可以看到不同的align属性,作用在不同的元素上,align属性的意义也不同。
问题:
firefox,chrome,safari会将div,H1~H6 P元素的align=“middle”解析为align=“center”。从而使这些元素能够居中对齐。
火狐混杂模式会将table元素align=“middle”解析为align=”center“,使table居中对齐。
IE6/7 ,chrome safari opera及ie8,firefox的混杂模式下,会将td,th元素的align=”middle“理解为align=”center“。
影响:
不正确使用align属性的”middle“属性值会在各浏览器中对应用元素的对齐方式产生差异,从而造成布局上的兼容性问题。
解决方案:
align="middle" 仅在 IMG、OBJECT、APPLET 元素上的 align 属性中是合法值,对于其他元素的 align 属性均为非法。各浏览器在上述三个元素之外的元素上遇到 align="middle" 均按照自己的理解方式解释。同时除单元格元素的 align 属性之外,其他的 align 属性均被 W3C 官方废弃(Deprecated.),所以应避免使用此属性。
align="middle" 仅在 IMG、OBJECT、APPLET 元素上的 align 属性中是合法值,对于其他元素的 align 属性均为非法。各浏览器在上述三个元素之外的元素上遇到 align="middle" 均按照自己的理解方式解释。同时除单元格元素的 align 属性之外,其他的 align 属性均被 W3C 官方废弃(Deprecated.),所以应避免使用此属性。
问题:
字体的样式会影响根据input元素的”size“属性计算的文本框宽度,其中包括”font-family","font-size","font-syle","letter-spacing".若仅仅为input元素设置“size”属性,却没有显式地设定宽度,则在不同的浏览器中input元素会出现不同的宽度。
解决方案:
不要试图通过设置 "size" 属性使 INPUT[type=text/password] 元素在所有浏览器中的宽度一致,这是不可能的。在需要对这类元素做精确的控制时,应使用 CSS 的 'width' 和 'height' 特性。
另外不同浏览器的默认字体的区别会导致文本框内文字表现的差异,最好为 INPUT 元素显式设置字体样式覆盖其默认值,以保证文本框在所有浏览器中有相同的呈现效果。
W3C没有规定用户端用于隐藏用户实际输入文本的“掩码”的文字编码和相关字体特性。
问题:
密码框中的掩码用来覆盖密码明文,它没有相应规范指定统一显示样式,因此导致不同系统与不同浏览器中密码框“input[type="password"]的掩码字符均有很大的差异。可幸的是,这种差异只会在视觉上产生不同,而不会造成布局上的差异。
检查浏览器对于 input[type=password] 标记的相关默认字体样式设置:
汇总后得到如下字体样式的差异表:
IE6 IE8 IE8(EmulateIE7) | IE7 Firefox | Safari | Chrome | Opera | |
---|---|---|---|---|---|
font-family | Tahoma | SimSun | SimSun | Arial | 宋体 |
font-weight | 400 | 400 | normal | normal | 400 |
font-size | 13px | 13px | 13px | 13px | 13px |
可见各浏览器中 'font-weight' 及 'font-size' 定义没有差异。
查看掩码字符,过滤的众多可疑的圆点字符后,总结出下表:
IE7 Firefox | IE6 IE8 Chrome Safari | Opera | |
---|---|---|---|
TEXT-UNICODE | 0x25cf | 0x2022 | 0x002a |
将上下两表结合,重现各浏览中掩码字符的默认样式如下:
IE6 IE8 IE8(EmulateIE7) | IE7 Firefox | Safari | Chrome | Opera | |
---|---|---|---|---|---|
font-family | Tahoma | SimSun | SimSun | Arial | 宋体 |
font-weight | 400 | 400 | normal | normal | 400 |
font-size | 13px | 13px | 13px | 13px | 13px |
TEXT-UNICODE | 0x2022 | 0x25cf | 0x2022 | 0x2022 | 0x002a |
显示效果 | ●●● | ●●● | ••• | ••• | *** |
解决方案:
由于掩码字符无法被修改,因此仅通过 CSS 统一密码输入框的掩码样式是不可能的。且这种差异可以忽略不计。
这里给出两种解决思路:
规范中对object元素的渲染规则:
问题:
firefox opera中object元素的默认尺寸为不可视,而IE中,object默认尺寸为16*16PX,在chrome和safari中默认尺寸为300*150px。
也就是说,如果没有为object元素设置明确的宽度和高度,则可能在各浏览器中由于其内在尺寸不同导致最终布局上的差异。
解决方案:
OBJECT 元素为替换元素,应为 OBJECT 元素设置一个明确的宽度和高度。
解决方案:
当我们仅仅为 TEXTAREA 元素设置 "rows" 属性以控制其高度时,在 Firefox 中无法得到我们预期的效果。且其他浏览器对 "rows" 属性设置的元素高度也不尽相同,这一点 W3C 没有明确规范 "rows" 属性计算高度时的具体算法。
如果要精确控制 TEXTAREA 元素的尺寸(高度)时,请避免使用 "rows" 属性改用 CSS 相关设定,以保证所有浏览器拥有统一的视觉样式。