【分享】CSS Hack的基本原理、常用CSS hack及使用原则

WebAdvocate 2010-07-15 05:23:49
加精
学习CSS,除了基础,还有必学的一课,就是CSS hack,很多书籍上都有涉及。当时觉得这个东西很神秘,可以针对某个或某些浏览器写些特别的 CSS 样式而不影响其他,而且用起来也很方便。
虽然如此,但是,很少有人知道,它到底是什么东西,使用CSS hack好不好,以及它是怎样实现的?
下面,就谈一下我对CSS hack的认识。希望能帮助大家正确的认识CSS hack。
介绍之前,请先记住一句话:你今天用CSS hack解决兼容性问题,明天浏览器就可能让你那解决问题的CSS hack变成另一个兼容性问题。


CSS hack简介

这,还要从W3C CSS2.1的标准说起。
W3C CSS2.1的标准的第四章,讲了CSS的基本语法,数据,以及值,还讲到了如何去处理不合理的值及声明等。可以参考我分享的另外两个帖子:【分享】说说标准 --CSS标准中的值【分享】说说标准--我 的眼里只有你--CSS的错误解析规则
W3C CSS2.1 标准也规定了浏览器应当支持的特性属性或值。
虽然如此,W3C也不可能强制浏览器厂商必须遵循标准。因此就出现了各大厂商对标准的实现不尽相同的现象。由于不同的浏览器,比如IE6、 IE7、 IE8、 Firefox等,对CSS解析的标准不同,因此对于相同的 CSS代码,可能会生成不同的页面效果,从而无法在所有浏览器中得到我们想要的效果。这时,我们就需要针对不同的浏览器去写不同的CSS代码,让它能够在所有浏览器中获得相同的效果。这个过程,就是CSS hack。也就是写出只有个别浏览器或某些浏览器识别的CSS代码。
CSS hack是因为现有浏览器对标准的解析不同,为了兼容各浏览器,所采用的一种补救方法。
CSS hack是一种类似作弊的手段,以欺骗浏览器的方式达到兼容的目的,是用浏览器的兼容性差异来解决浏览器的兼容性问题。
因此,在设计之初,写CSS hack需要遵循以下三条原则:
有效: 能够通过 Web 标准的验证
只针对太古老的/不再开发的/已被抛弃的浏览器, 而不是目前的主流浏览器
代码要丑陋。让人记住这是一个不得已而为之的 Hack, 时刻记住要想办法去掉它。
现在很多hacks已经抛弃了最初的原则,而滥用hack会导致浏览器更新之后产生更多的兼容性问题。
因此,并不推荐使用CSS hack来解决兼容性问题


CSS hack的实现方式

我总结了一下,实现CSS hack大概有以下几种方式:
1. 利用浏览器对相同代码的解析和支持的不同实现的hack
不同浏览器对相同的CSS代码的支持情况可能不同。尤其是对错误的写法。
例如,
#test{
_width:80px;
}
在IE7及以上版本的浏览器中会被当作错误特性而舍弃,但是在IE6中可以被正常的解析。这时候,可以把_width当作hack,专门针对 IE6来设置元素的宽度。
2. 以Firefox或Webkit特有的扩展样式实现的hack
以-moz或-webkit开头的扩展样式,是浏览器对CSS标准的扩展。这些特性只在相应的浏览器里才可以被正常的解析。 因此可以被当作CSS hack来使用。
以-moz开头的Firefox特有扩展样式
Mozilla浏览器支持的一些扩展是以-moz开头的。这些扩展包括了一些功能,例如圆形边界等。这种CSS只适用于Mozilla浏览器。
比如,-moz-opacity是在Firefox2.0版本出现的特性,用来实现元素的透明,但Firefox3.0以后的版本中不再支持,而是直接支持标准中的opacity特性。而其他浏览器不支持-moz-opacity。所以,可以使用-moz-opacity来针对Firefox2.0设置元素的透明度。
关于Firefox扩展样式的详细信息,见Mozilla CSS Extensions
以-webkit开头的Webkit浏览器特有扩展样式
与以-moz开头的Firefox特有扩展样式相同,以-webkit开头的样式是 Webkit浏览器特有的,只有Webkit浏览器可以解析。
比如,在Webkit浏览器中可以用 -webkit-border-radius实现圆角。
3. 利用IE对标准的支持缺陷写的CSS hack
这个类别以中的hack以IE对标准的支持缺陷为基础,可以让CSS代码针对IE6或IE7以外的浏览器生效。
例如,!important只有IE7及以上版本的IE及其他浏览器支持,所以,可以用!important来针对IE6以外的浏览器写 CSS代码;再如,head:first-child+body selector,:first-child不被IE6支持,所以可以用来针对IE6以外的浏览器编写CSS代码。
此处不在一一列举。
当然,有的观点认为应用CSS2.1标准,不属于CSS hack。见Tantek's Thoughts,Using A CSS2 Feature Is NOT a Hack。
4. 以IE特有的条件注释为基础的hack
IE浏览器中特有的条件注释也经常被用作 hack,可以针对特定版本的IE写CSS代码。
例如,测试用例:
<!--[if IE 8]>
<style type="text/css">
#test {
color: red;
}
</style>
<![endif]-->
<h1 id="test">TEXT</h1>
以上代码中的 "TEXT",只在IE8中才会是红色。


CSS hack汇总表

为了使用方便,我搜了好多关于CSS hack的内容,其中还有一个比较著名的CSS hack汇总表,看起来不错,但用起来,发现,有些已经不适用了。因为,浏览器版本更新的太快了。
大多数人应该都很熟悉这张表吧:

这表看起来很壮观,但是,里面的数据都已经很陈旧了。也许你的hack今天还有效,明天浏览器版本更新后,便失去了效果。所以,慎用hack。

我结合上表,又收集了一下网上较为常用的的CSS hack,整理出一个Windows系统下各浏览器常用CSS hack汇总表,如下:
说明:
1. 此汇总表中测试浏览器的版本为
o IE6
o IE7
o IE8
o Firefox 3.6.6
o Safari 5.0
o Chrome 6.0.458.1 dev
o Opera 10.60
2. 其中,多数CSS hack是在selector{property:value;}基础上更改的。selector代表CSS选择器,property代表CSS特性,value代表特性的值。
3. FF代表Firefox,Ch代表Chorme,Sa代表Safari,Op代表Opera
4. Q代表Quirks Mode,S代表Standards Mode。
5. Hack Type列的数字,指的是上面CSS hack的实现方式中的列表号。1是指“利用浏览器对相同代码的解析和支持的不同实现的hack”,2是指以Firefox或Webkit特有的扩展样式实现的hack。


其中 *+html selector 的测试用例:
<style type="text/css">
*+html #test {
color: red;
}
</style>
<h1 id="test">TEXT</h1>
其他测试用例可在此基础上修改。

切记,遵守CSS hack的三条原则。CSS hack是没有办法的时候才使用的解决兼容性问题的招术,是用兼容性问题去解决兼容性问题,无异于饮鸩止渴。切莫一有兼容性问题就使用。
另外,时刻记得改掉用CSS hack修补的问题。

补充一点儿好玩儿的东西,Yahoo也有一种实现hack的方式,比较特殊。Yahoo会利用服务器去判断打开其页面的浏览器的类别,然后,把信息加到HTML标签上,比如我使用Firefox打开Yahoo的首页,查看它的HTML标签,发现:
<html lang="en-US" class="y-fp-bg y-fp-pg-grad ua-ff ua-win ua-ff3_6  bkt701">……</html>
注意其中的ua-ff ua-win ua-ff3_6,含有浏览器类别和版本的信息。
然后,在设置特定浏览器的样式时,比如,我希望在Firefox里让所有的div中的文字都是红色,可以这样设置:
.ua-ff div{
color : red;
}
呃~~,,我觉得这也可以叫做CSS hack。

更多兼容性问题,见:【分享】浏览器兼容性问题目录
...全文
8229 99 打赏 收藏 转发到动态 举报
写回复
用AI写文章
99 条回复
切换为时间正序
请发表友善的回复…
发表回复
小程序原 2012-06-08
  • 打赏
  • 举报
回复
不错,很有实用价值啊。赞!
win7dellxps 2012-02-17
  • 打赏
  • 举报
回复
这个系列不错!
yubao2008 2011-12-20
  • 打赏
  • 举报
回复
楼主很强大
hat11223 2011-07-04
  • 打赏
  • 举报
回复
确实,良好的代码可以规避很多不需要的Hack
softroad 2011-05-23
  • 打赏
  • 举报
回复
不错,学习了。
wade419 2010-10-29
  • 打赏
  • 举报
回复
赞一个
YHL27 2010-08-24
  • 打赏
  • 举报
回复
learn fine..
xiaozy2 2010-08-18
  • 打赏
  • 举报
回复
LZ有空好好交流交流
liangshangjunzi 2010-08-17
  • 打赏
  • 举报
回复
好东西
wangxin929 2010-07-23
  • 打赏
  • 举报
回复
不错,web开发需要关注。
十一文 2010-07-23
  • 打赏
  • 举报
回复
学习了
xiaoxiangqing 2010-07-23
  • 打赏
  • 举报
回复
好好学习下。
lxh75 2010-07-23
  • 打赏
  • 举报
回复
今天学习了
lyp2281231 2010-07-22
  • 打赏
  • 举报
回复
每一天回帖,100分
tigerhu76 2010-07-22
  • 打赏
  • 举报
回复
参考参考,谢谢提供。
wangshilei 2010-07-22
  • 打赏
  • 举报
回复
干嘛呢,干嘛呢,整啥呢,有啥好挣的
一起刷分子撒
petter101 2010-07-22
  • 打赏
  • 举报
回复
谢谢!
fly75554 2010-07-21
  • 打赏
  • 举报
回复
( ^_^ )不错嘛( ^_^ )不错嘛( ^_^ )不错嘛 我也要用
lijiezhao 2010-07-21
  • 打赏
  • 举报
回复
谢谢分享!
myshuangyuzuo 2010-07-21
  • 打赏
  • 举报
回复
学习下
加载更多回复(74)

5,006

社区成员

发帖
与我相关
我的任务
社区描述
解读Web 标准、分析和讨论实际问题、推动网络标准化发展和跨浏览器开发进程,解决各种兼容性问题。
社区管理员
  • 跨浏览器开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧