Web前端技术研究:Css hack技术---令人沮丧的技术
我最近想好好整理下csshack技术,但是结果很沮丧,下面我将我最初写的笔记和大家分享下。
我在单位整理的研究笔记:
不同的浏览器对某些CSS代码解析会存在一定的差异,因此就会导致不同浏览器下给用户展示的页面效果不一样,碰到这样的情况就需要开发人员通过针对不同的浏览器对应写出不同的CSS代码,从而达到兼容不同浏览器的目的,不会让页面因为浏览器的不同而产生有差异的显示,这种技术有个专门的名称就是CSS Hack。
在中国,这种差异主要是体现在主流浏览器上,我们只要解决了主流浏览器之间的CSS差异就可以了。目前流行的主流浏览器有Internet Explorer,Google Chrome,FireFox,Apple Safair以及Opera,在本文里对应简称为IE(后面如果添加数字,数字代表版本号,例如IE8),CH,FF,SA和OP。
CSS Hack原理是通过不同浏览器自身所带有的特别标识符以及CSS中优先级的机制来实现不同浏览器里CSS样式兼容性的问题。
CSS Hack有三种实现方式,它们分别是:CSS类内部的Hack、CSS选择器的Hack和HTML头部的Hack。
CSS类内部的Hack:是指CSS属性或属性值里加上只有某个浏览器自己可以识别的特殊字符串。例如IE6和IE7都会识别在CSS里属性名称前加上“*”号的属性,但是firefox却无法识别带“*”号的属性,因此下面的代码:
body{ background:green; /* firefox下的显示 */ *background:red; /* IE6和IE7下的显示 */ }
CSS选择器的Hack:它是指在CSS选择器前面加上只有某种浏览器自己可以识别的特殊字符串。例如:IE6能识别*html .class{},IE7能识别*+html .class{}。
HTML头部的Hack:这种方式主要是针对IE浏览器,IE浏览器是广大Web前端工程师的痛,它不仅有很多自己独有的区别于其他浏览器的CSS样式,自己不同版本之间的CSS实现也会存在很大的差异。下面我们来看看这种方式的写法:
<!--[if lte IE 8]> <!-- IE条件注释-->
<link src="iecss.css" rel="stylesheet" />
<![endif]-->
这种写法会被非IE的浏览器所忽略,只有IE浏览器才会执行上面的代码,上面这段代码的意思是当IE的版本是8或者比8低的IE浏览器才会执行下面的样式。例子中有一个运算符号lte,它是less than or equal to的简写,意思是小于等于,其他的运算符号还有lt(less than,小于)、gte(greater than or equal to,大于等于)、gt(greater than,大于)。
下面我们来看一段代码:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>CSS hack技术</title> </head> <style type="text/css"> div{ width:400px; height:120px; margin-bottom:20px; border-style:solid; border-width:1px; } div.d01{ background:red;/* FF */ background:blue\0;/* OP */ background:turquoise\9;/* IE8+ */ [background:red;background:black;/* SA,CH */ *background:green; /* IE7 */ _background:yellow;/* IE6 */ } </style> <body> <div class="d01"></div> </body> </html>
运行这个页面,firefox显示的颜色是red,opera为blue,ie6为yellow,ie7为green,ie8以上的版本是turquoise,chrome和safari为blcak。这个CSS Hack是我平时常用的一套模式。这里要说明下,ie8以上包括ie8的CSS样式差异性较少,而chrome和safari之间的CSS样式差异较小,因此这里我并没有为它们单独进行hack。
如果我们把上面代码里的div.d01的内容顺序调整下,例如下面这样:
background:blue\0;/* OP */ background:turquoise\9;/* IE8+ */ [background:red;background:black;/* SA,CH */ *background:green; /* IE7 */ _background:yellow;/* IE6 */ background:red;/* FF */
我们会发现不同浏览器显示的效果就会发生变化。ie8以上的版本以及opera显示正常,但是chrome,safari,ie6,ie7显示的是红色,而firefox则没有任何颜色。引起这个问题的原因是CSS优先级的问题,例如background:turquoise\9;这种写法不会导致高版本的ie在显示上产生偏差,是因为高版本的ie会优先使用这个样式,对于同级别的CSS样式,最后面的样式会覆盖前面的样式,例如我们在ie6和ie7下看到的情况,此外,如果正确的样式前面的样式写法导致浏览器无法正常解析,那么就会导致整个CSS样式加载的失败,例如firefox。
因此编写CSS Hack时候,对于属性排列的顺序是特别注意的。
CSS Hack是一个总结性和经验性很强的技术,它不像很多编程技术那样需要我们去反复理解一些逻辑上的关系,而是需要我们平时多留心,多实践。接下来我将会列举不同浏览器之间的CSS Hack技术,大家可以根据自己实际的情况选择应用。
对于ie,我们这边主要考虑ie6,ie7,ie8,ie9,这四种版本的ie是目前中国市场上最流行的ie版本,虽然ie10已经出来,但是ie10现在使用的用户相对较少,这边不会作为重点讲解。
对于CSS类内部的Hack ,ie6有自己专有的判断标识“_”,其他的浏览器都不会识别”_”,ie6也支持”*”,但是“*”也被ie7识别,因此当我们只想区别ie6和ie7的时候,可以按下面的代码书写:
div.d02{ *background:green; /* IE7 */ _background:yellow;/* IE6 */ }
上面的写法既可以区分ie6和ie7,但是如果我们颠倒其位置,那么不管是ie6还是ie7都会显示green颜色。”*”和“_”是ie6和ie7专属的,其他版本的浏览器都不支持该标记。
ie6和ie7除了上面两个专属标记,IE6还能识别能识别*html selector{},IE7还能能识别*+html . selector {},大家看下面这段代码:
*html div.d03{ background:yellow;/* IE6 */ } *+html div.d03{ background:green;/* IE7 */ }
这两种写法是等价的。IE6的*html selector {}和IE7的*+html . selector {}也都是专有标记,别的浏览器都不会识别的。
还有个很有趣的标记,就是!important,在网上很多资料说该标记IE6不支持,IE7和firefox支持,为了验证网上说法本人写了下面的样式:
div.d04{ background:red !important; }
我使用的浏览器配置如下:
支持IE7,IE8,IE9;IE6通过ietester实现;firefox版本是23.0.1;chrome的版本是27.0.1453.116 m;opera的版本是12.12,运行上面的样式实际的效果是:
IE6,IE7,chrome,safari显示为红色,而其他浏览器都没有显示任何颜色。
这样说明随着浏览器的不断升级,csshack技术也是发生变化的,在使用一些现成的css hack代码时候,如果当不到预期效果是很正常,这时就需要我们细心的测试,找出最好的解决方案。
以上的文字都是我在单位电脑上进行开发写出来,我家里的笔记本重装了操作系统,所有的浏览器都进行了重装,现在都是最新的版本,当我把下面的代码再执行下时候:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>CSS hack技术</title> </head> <style type="text/css"> div{ width:400px; height:120px; margin-bottom:20px; border-style:solid; border-width:1px; } div.d01{ background:red;/* FF */ background:blue\0;/* OP */ background:turquoise\9;/* IE8+ */ [background:red;background:black;/* SA,CH */ *background:green; /* IE7 */ _background:yellow;/* IE6 */ } </style> <body> <div class="d01"></div> </body> </html>
上面的代码显示的是:
Ie6是yellow,ie7是green,ie8和ie9和ie10是turquoise,op和sa是black,ch则变为了red,ff还是red。
op和ch显示和我单位不一样了。
我笔记本上的浏览器版本是:Ie7,ie8,ie9,ie10,ietester的ie6,op是15.0,ch是29.0.1547.57,sa是5.1.7,ff是23.0.1;
这和我单位电脑不一样,公司的电脑是(支持IE7,IE8,IE9;IE6通过ietester实现;firefox版本是23.0.1;chrome的版本是27.0.1453.116 m;opera的版本是12.12)
Csshack技术的研究是个十分令人泄气的事情,网上的资料几乎都已经作废了,每次浏览器的升级都会导致你的csshack的失败。
不过这里我还是想请教下看到本文的大牛,谁能给一个完美的css能区别开所有的浏览器。