一、什么是CSS hack
在书写CSS样式的时候经常遇到就浏览器兼容的问题,比如说不同厂商的浏览器,或是同一厂商的浏览器的不同版本浏览器、不同的浏览器对CSS样式的解析是不同的,因此就会导致其在页面输出的是不同的效果,这个时候就需要使用CSS hack来解决浏览器的兼容问题。
使用CSS hack去解决浏览器局部兼容问题,也可以通过CSS hack为不同版本的浏览器定制编写不同的CSS效果。
二、CSS hack简介
CSS hack是通过在CSS样式中加入特殊符号,让浏览器是别不同的符号(不同的有其对应的不同标准),以达到应用到不同的CSS样式的目的,即Hack(修改)。
举个例子:
.test { color: #090; *color: #f00; /* For IE7 and earlier */ _color: #ff0; /* For IE6 and earlier */ }
在这段代码中,一般情况下浏览器会先设置color:#090;这个样式。
后面*color: #f00; 只有在IE7浏览器中才可以识别,所以IE7里面字体颜色就是 #f00;
*color: #ff0; 只有在IE6浏览器中才可以是识别,所以IE6浏览器显示字体颜色是#ff0;
遇到对应的浏览器,后面的样式就会将前面的样式覆盖。其他浏览器不会识别*color或_color,所以在其他浏览器中字体颜色就是#090;
解决各个浏览器对CSS解释不同,所采取的的区别不同浏览器制作不同的CSS样式,的设置来解决这些问题就叫做CSS hack
三、CSS Hack三种形式
CSS hack三种形式:1、条件注释Hack;2、属性级Hack;3、选择符Hack
(一)条件注释Hack
语法:
<!--[if <keywords>? IE <version>?]> HTML代码块 <![endif]-->
<keywords>:
if条件中共包含6种选择方式:是否、大于、小于或等于、非指定版本
是否:指定是否IE或IE某个版本。关键字:空
大于:选择大于指定版本的IE版本。关键字:gt(greater than)
大于或等于:选择大于或等于指定版本的IE版本。关键字:gte(greater than or equal)
小于:选择小于指定版本的IE版本。关键字:lt(less than)
小于或等于:选择小于或等于指定版本的IE版本。关键字:lte(less than or equal)
非指定版本:选择除指定版本外的所有IE版本。关键字:!
<version>:
目前使用的版本基本上都在IE6以上,没有必要去太过纠结过低的版本。现在IE10已经将条件注释移除,不再支持。
条件注释Hack用于选择IE浏览器以及IE浏览器不同的版本(if条件Hack是HTML级别的(包含但不仅是针对CSS的Hack,可以选择任何HTML代码块))
1、不想在非IE浏览器中看到某区域:
这样在非IE的浏览器中就不会看到p元素的代码块
<!--[if IE]> <p>你在非IE中将看不到我的身影</p> <![endif]-->
2、是否:指定是否IE或IE某个版本
只有在IE浏览器中才能看到id为box的元素的字体颜色为red
<!--[if IE]> <style> #box{color:red;} </style> <![endif]-->
3、大于:选择大于指定版本的IE版本
只有在IE7以上的版本中,才能看到id为box的元素的字体颜色为red
<!--[if gt IE 7]> <style> #box{color:red;} </style> <![endif]-->
4、大于或等于:选择大于或等于指定版本的IE版本
只有在IE7及以上的版本中,才能看到id为box的元素的字体颜色为red
<!--[if gte IE 7]> <style> #box{color:red;} </style> <![endif]-->
5、小于:选择小于指定版本的IE版本
只有在小于IE9的版本中,才能看到id为box的元素的字体颜色为red
<!--[if lt IE 9]> <style> #box{color:red;} </style> <![endif]-->
6、小于或等于:选择小于或等于指定版本的IE版本
只有在小于或等于IE9的版本中,才能看到id为box的元素的字体颜色为red
<!--[if lte IE 9]> <style> #box{color:red;} </style> <![endif]-->
7、非指定版本:选择除指定版本外的所有IE版本
除了IE7以外的版本,都可以看到id为box的元素的字体颜色为red
<!--[if ! IE 7]> <style> #box{color:red;} </style> <![endif]-->
(二)属性级Hack
语法:
selector{<hack>?property:value<hack>?;}
符号:
_:选择IE6及以下。连接线(中划线)(-)亦可使用,为了避免与某些带中划线的属性混淆,所以使用下划线(_)更为合适。
*:选择IE7及以下。诸如:(+)与(#)之类的均可使用,不过业界对(*)的认知度更高
\9:选择IE6+
\0:选择IE8+和Opera15以下的浏览器
如果想让一段文字在IE6/7/8中分别显示不同的颜色,可以采用如下写法:
.test { color: #090\9; /* For IE8+ */ *color: #f00; /* For IE7 and earlier */ _color: #ff0; /* For IE6 and earlier */ }
注意:上述Hack均需要尊姓在标准模式下,若在怪异模式下,这些Hack将会被不同版本的IE相互识别,导致失效。
(三)选择符级Hack
语法:
<hack> selector{ sRules }
常用的:
大部分特殊字符IE浏览器支持,其他主流浏览器firefox,chrome,opera,safari不支持 (opera可识别除外)。\9 :所有IE浏览器都支持_和- :仅IE6支持* :IE6、E7支持\0 :IE8、IE9支持,opera部分支持\9\0 :IE8部分支持、IE9支持\0\9 :IE8、IE9支持
IE浏览器各版本 CSS hack 对照表
hack |
写法 |
实例 |
IE6(S) |
IE6(Q) |
IE7(S) |
IE7(Q) |
IE8(S) |
IE8(Q) |
IE9(S) |
IE9(Q) |
IE10(S) |
IE10(Q) |
* |
*color |
青色 |
Y |
Y |
Y |
Y |
N |
Y |
N |
Y |
N |
Y |
+ |
+color |
绿色 |
Y |
Y |
Y |
Y |
N |
Y |
N |
Y |
N |
Y |
- |
-color |
黄色 |
Y |
Y |
N |
N |
N |
N |
N |
N |
N |
N |
_ |
_color |
蓝色 |
Y |
Y |
N |
Y |
N |
Y |
N |
Y |
N |
N |
# |
#color |
紫色 |
Y |
Y |
Y |
Y |
N |
Y |
N |
Y |
N |
Y |
\0 |
color:red\0 |
红色 |
N |
N |
N |
N |
Y |
N |
Y |
N |
Y |
N |
\9\0 |
color:red\9\0 |
粉色 |
N |
N |
N |
N |
N |
N |
Y |
N |
Y |
N |
!important |
color:blue !important;color:green; |
棕色 |
N |
N |
Y |
N |
Y |
N |
Y |
N |
Y |
Y |
四、不推荐使用CSS hack
在制作Web页面的时候尽量不要使用CSS Hack来处理兼容问题。
因为任何浏览器下出现渲染不一致都有可能是因为自己写的样式结构不符合W3C的某些要求,或者说违背了浏览器的某些规则造成,而且滥用CSS Hack还会导致很多浏览器兼容问题;
所以应该尽量通过结构或是CSS的修改来达到各个浏览器渲染效果一致,不到迫不得已的情况下,不考虑CSS Hack。
五、慎用\0的CSS Hack
不能够简单地下结论说,使用\0可以实现对IE 8、IE 9甚至IE 10 +的CSS Hack。
将下面的代码在不同的IE版本中打开。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .hack{ color: red; /* 其他浏览器显示红色 */ color: blue\0; /* IE8、IE9 显示蓝色 */ +color: green; /* IE7 显示绿色 */ _color: brown; /* IE6 显示棕色 */ } </style> </head> <body> <div class="hack">111111111</div> </body> </html>
我们通常认为字符 \0 可以支持 IE8、9浏览器。
经过对上面代码的测试后发现,关于使用 字符\0 实现上述CSS Hack有几点需要注意。
1、IE10也能够识别添加了字符 \0 的 CSS样式。
2、属性值和 \0 中不可以用空格,如果有空格在IE8中就失效了,使用空格的 \0 仅仅对IE9和IE10有效;
如果指向对IE8和IE9使用CSS Hack,该怎么做的?
.css-hack { color: red; /* 其他浏览器显示红色 */ color: blue\0; /* IE8、IE9 显示蓝色 */ }
这是因为,一般浏览器的思路是先过滤掉无用的CSS样式,然后再从正确的属性中根据样式优先级获取排在最后的CSS属性。
IE6/7 浏览器就比较另类,不是先过滤掉无效的属性值,而是先根据优先级,获取最后面的CSS样式并判断该样式是否有效,如果无效就忽略,使用默认值。
所以,仅仅使用 \0 来实现 IE8+ 的CSS Hack 就会破坏 IE6/7 的显示效果。这时候就需要设置额外的CSS属性来恢复 IE6/7 的样式。
六、各个浏览器中Hack的写法
@-moz-document url-prefix() { .selector { property: value; } }
上面是仅仅被Firefox浏览器识别的写法,具体如:@-moz-document url-prefix() { .demo { color:lime; } }
支持Firefox的还有几种写法:
/* 支持所有firefox版本 */ #selector[id=selector] { property: value; } 或者: @-moz-document url-prefix() { .selector { property: value; } } /* 支持所有Gecko内核的浏览器 (包括Firefox) */ *>.selector { property: value; }
2、Webkit枘核浏览器(chrome and safari)
@media screen and (-webkit-min-device-pixel-ratio:0) { Selector { property: value; } }
上面写法主要是针对Webkit内核的浏览器,如Google Chrome 和 Safari浏览器:
@media screen and (-webkit-min-device-pixel-ratio:0) { .demo { color: #f36; } }
html:first-child>body Selector {property:value;} 或者: @media all and (min-width:0) { Selector {property: value;} }
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) { head~body .demo { background: green; } }
:root Selector {property: value9;}
上面是IE9的写法,具体应用如下::root .demo {color: #ff09;}
这种写法只有IE9以及IE9以下版本能识别,这里需要注意此处“9”只能是“9”不能是别的,比如说“8”,不然会失去效果的,如:.demo {background: lime9;}
Selector {property: value\0;}
这种写法只有IE8以及IE8以上版本支持,如.demo {color: #ff0;}
*+html Selector{property:value;} 或 *:first-child+html Selector {property:value;}
上面两种是IE7浏览器下才能识别,如:*+html .demo {background: green;} 或者: *:first-child+html .demo {background: green;}
Selector {*property: value;}
上面的写法在IE7以及其以下版本都可以识别,如:.demo {*background: red;}
10、IE6浏览器
Selector {_property/**/:/**/value;} 或者: Selector {_property: value;} 或者: *html Selector {property: value;}
具体应用如下:.demo {_width/**/:/**/100px;} 或者: .demo {_width: 100px;} 或者: *html .demo {width: 100px;}
参考文章: