什么是CSS黑客
由于不同厂商的流览器或某浏览器的不同版本(如IE6,IE11,火狐/ Safari浏览器/歌剧/铬等),对CSS的支持,解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果。这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的CSS样式,我们把这个针对不同的浏览器/不同版本写相应的CSS代码的过程,叫做CSS破解!
CSS hack的原理
由于不同的浏览器和浏览器各版本对CSS的支持及解析结果不一样,以及CSS优先级对浏览器展现效果的影响,我们可以据此针对不同的浏览器情景来应用不同的CSS。
CSS hack分类
CSS Hack大致有3种表现形式,CSS属性前缀法,选择器前缀法以及IE条件注释法(即HTML头部引用if IE)Hack,实际项目中CSS Hack大部分是针对IE浏览器不同版本之间的表现差异而引入的。
- 属性前缀法(即类内部Hack):例如IE6能识别下划线“_”和星号“*”,IE7能识别星号“*”,但不能识别下划线“_”,IE6~IE10都认识“\ 9 “,但Firefox的前述三个都不能认识。
- 选择器前缀法(即选择器Hack):例如IE6能识别* html .class {},IE7能识别* + html .class {}或者*:first-child + html .class {}。
- IE条件注释法(即HTML条件注释Hack):针对所有IE(注:IE10 +已经不再支持条注注释):<! - [if IE]> IE浏览器显示的内容<![endif] - > ,针对IE6及以下版本:<! - [if lt IE 6]>只在IE6-显示的内容<![endif] - >。这类Hack不仅对CSS生效,对写在判断语句里面的所有代码都会生效。
CSS hack书写顺序,一般是将适用范围广,被识别能力强的CSS定义在前面。
CSS hack方式一:条件注释法
这种方式是IE浏览器专有的哈克方式,微软官方推荐使用的劈方式。举例如下
只在IE下生效 <! - [if IE]> 这段文字只在IE浏览器显示 <![ENDIF] - > 只在IE6下生效 <! - [如果IE 6]> 这段文字只在IE6浏览器显示 <![ENDIF] - > 只在IE6以上版本生效 <! - [if gte IE 6]> 这段文字只在IE6以上(包括)版本IE浏览器显示 <![ENDIF] - > 只在IE8上不生效 <! - [如果!IE 8]> 这段文字在非IE8浏览器显示 <![ENDIF] - > 非IE浏览器生效 <! - [if!IE]> 这段文字只在非IE浏览器显示 <![ENDIF] - >
CSS hack方式二:类内属性前缀法
属性前缀法是在CSS样式属性名前加上一些只有特定浏览器才能识别的黑客前缀,以达到预期的页面展现效果。
IE浏览器各版本CSS hack对照表
劈 | 写法 | 实例 | IE6(S) | IE6(Q) | IE7(S) | IE7(Q) | IE8(S) | IE8(Q) | IE9(S) | IE9(Q) | IE10(S) | IE10(Q) |
* | *颜色 | 青色 | ÿ | ÿ | ÿ | ÿ | ñ | ÿ | ñ | ÿ | ñ | ÿ |
+ | +颜色 | 绿色 | ÿ | ÿ | ÿ | ÿ | ñ | ÿ | ñ | ÿ | ñ | ÿ |
- | -颜色 | 黄色 | ÿ | ÿ | ñ | ñ | ñ | ñ | ñ | ñ | ñ | ñ |
_ | _颜色 | 蓝色 | ÿ | ÿ | ñ | ÿ | ñ | ÿ | ñ | ÿ | ñ | ñ |
# | #颜色 | 紫色 | ÿ | ÿ | ÿ | ÿ | ñ | ÿ | ñ | ÿ | ñ | ÿ |
\ 0 | 颜色:红色\ 0 | 红色 | ñ | ñ | ñ | ñ | ÿ | ñ | ÿ | ñ | ÿ | ñ |
\ 9 \ 0 | 颜色:红色\ 9 \ 0 | 粉色 | ñ | ñ | ñ | ñ | ñ | ñ | ÿ | ñ | ÿ | ñ |
!重要 | 颜色:蓝色!重要;颜色:绿色; | 棕色 | ñ | ñ | ÿ | ñ | ÿ | ñ | ÿ | ñ | ÿ | ÿ |
说明:在标准模式中
- “ - “减号是IE6专有的黑客
- “\ 9”IE6 / IE7 / IE8 / IE9 / IE10都生效
- “\ 0”IE8 / IE9 / IE10都生效,是IE8 / 9/10的黑客
- “\ 9 \ 0”只对IE9 / IE10生效,是IE9 / 10的黑客
演示如下
-
< script type =“ text / javascript ”>
-
// alert ( document .compatMode );
-
</ script >
-
< style type =“ text / css ”>
-
body :nth-of-type(1) .iehack {
-
颜色 : #F00 ; / *对Windows IE9 / Firefox 7 + / Opera 10 + /所有Chrome / Safari的CSS hack,选择器也适用几乎全部Mobile / Linux / Mac浏览器* /
-
}
-
.demo1 , .demo2 , .demo3 , .demo4 {
-
宽度 : 100px ;
-
身高 : 100px ;
-
}
-
.hack {
-
/ * demo1 * /
-
/ * demo1注意顺序,否则IE6 / 7下可能无法正确显示,导致结果显示为白色背景* /
-
背景颜色 :红色; / *所有浏览器* /
-
background-color :blue ; / *所有浏览器,但IE6 * /
-
* 背景颜色 :黑色; / * IE6,IE7 * /
-
+ 背景色 :黄色; / * IE6,IE7 * /
-
background-color :grey \ 9 ; / * IE6,IE7,IE8,IE9,IE10 * /
-
background-color :purple \ 0 ; / * IE8,IE9,IE10 * /
-
background-color :orange \ 9 \ 0 ; / * IE9,IE10 * /
-
_background-color :绿色; / *仅适用于IE6 * /
-
* + 背景色 :粉色; / *警告:仅适用于IE7?这样对吗?* /
-
}
-
-
/ *可以通过javascript检测IE10,然后给IE10的<html>标签加上class =“ie10”这个类* /
-
.ie10 #hack {
-
颜色 :红色; / *仅适用于IE10 * /
-
}
-
-
/ * * DEMO2 /
-
.iehack {
-
/ *该演示实例是用于区分标准模式下的IE6〜IE9和火狐/ Chrome浏览器的黑客攻击,注意顺序
-
IE6显示为:绿色,
-
IE7显示为:黑色,
-
IE8显示为:红色,
-
IE9显示为:蓝色,
-
火狐/ Chrome浏览器显示为:橘色,
-
(本例IE10效果同IE9,歌剧最新版效果同IE8)
-
* /
-
背景颜色 :橙色; / * all - 适用于Firefox / Chrome * /
-
background-color :red \ 0 ; / * ie 8/9/10 / Opera - for ie8 / ie10 / Opera * /
-
background-color :blue \ 9 \ 0 ; / *即9/10 - 对于ie9 / 10 * /
-
* 背景颜色 :黑色; / *即6/7 - 对于ie7 * /
-
_background-color :绿色; / *即6 - 对于ie6 * /
-
}
-
-
/ * demo3
-
实例是用于区分标准模式下的IE6〜IE9和火狐/ Chrome浏览器的黑客攻击,注意顺序
-
IE6显示为:红色,
-
IE7显示为:蓝色,
-
IE8显示为:绿色,
-
IE9显示为:粉色,
-
火狐/ Chrome浏览器显示为:橘色,
-
(本例IE10效果同IE9,歌剧最新版效果也同IE9为粉色)
-
-
* /
-
.element {
-
背景颜色 :橙色; / *所有IE / FF / CH / OP * /
-
}
-
.element {
-
* 背景颜色 :蓝色; / * IE6 + 7,在IE8 / 9中不能用作IE7 * /
-
}
-
.element {
-
_background-color :红色; / * IE6 * /
-
}
-
.element {
-
background-color :green \ 0 ; / * IE8 + 9 + 10 * /
-
}
-
:root .element { background-color :pink \ 0 ; } / * IE9 + 10 * /
-
-
/ * * demo4 /
-
/ *
-
-
该实例是用于区分标准模式下的IE6〜IE10和歌剧/火狐/ Chrome浏览器的黑客,本例特别要注意顺序
-
IE6显示为:橘色,
-
IE7显示为:粉色,
-
IE8显示为:黄色,
-
IE9显示为:紫色,
-
IE10显示为:绿色,
-
火狐显示为:蓝色,
-
歌剧显示为:黑色,
-
Safari /铬显示为:灰色,
-
-
* /
-
.hacktest {
-
背景颜色 :蓝色; / *都识别,此处针对firefox * /
-
background-color :red \ 9 ; / *全部即* /
-
background-color :黄色\ 0 ; / * for IE8 / IE9 / 10最新版opera也认识* /
-
+ 背景色 :粉红色; / *表示ie6 / 7 * /
-
_background-color :orange; / * for ie6 * /
-
}
-
-
@ media screen和(min-width: 0 ){
-
.hacktest { background-color :black \ 0 ;} / * opera * /
-
}
-
@ media screen和(min-width: 0 ){
-
.hacktest { background-color :purple \ 9 ; } / * for IE9 / IE10 PS:国外有些习惯常写作\ 0,根本没考虑Opera也认识\ 0的实际* /
-
}
-
@ media screen and(-ms-high-contrast:active),( - ms-high-contrast:none){
-
.hacktest { background-color :green; } / * for IE10 +此写法可以适应到高对比度和默认模式,故可覆盖所有ie10的模式* /
-
}
-
@ media screen和(-webkit-min-device-pixel-ratio: 0 ){。 hacktest { background-color :gray;}} / * for Chrome / Safari * /
-
-
/ *#963棕色:root用于IE9 / IE10,优先级高于@media,慎用!如果二者合用,必要时在@media样式加入!important才能区分IE9和IE10 * /
-
/ *
-
:root .hacktest {background-color:#963 \ 9; }
-
* /
-
</ style >
演示1是测试不同IE浏览器下黑客的显示效果
IE6显示为:粉色,
IE7显示为:粉色,
IE8显示为:蓝色,
IE9显示为:蓝色,
Firefox / Chrome / Opera显示为:蓝色,
若!去掉其中的重要属性定义,则IE6 / 7仍然是粉色,IE8是紫色,IE9 / 10为橙色,火狐/铬变为红色,歌剧是紫色是不是有些奇怪:除了IE6以外,其他所有的表现。都符合我们的期待那为何IE6表现的颜色不是_background色:绿色;的绿色而是* +的背景色:?粉红色的粉色呢其实是最后一句所谓的IE7私有的黑客惹的祸不是说* +是IE7的专有hack吗???错,你可能太粗心了!我们常说的IE7专有* + hack的格式是* + html选择器,而不是上面的直接在属性上加* +前缀。如果是为IE7定制特殊样式,应该这样使用:
* + html#ie7test {/ * IE7 only * / 颜色:绿色; }
经过测试,我发现属性前缀* + background-color:pink;只有IE6和IE7认识。而* + html选择器只有IE7认识。所以我们在使用时候一定要特别注意。
demo2实例是用于区分标准模式下ie6~ie9和Firefox / Chrome的hack,注意顺序
IE6显示为:绿色,
IE7显示为:黑色,
IE8显示为:红色,
IE9显示为:蓝色,
Firefox / Chrome显示为:橘色,
(本例IE10效果同IE9,Opera最新版效果同IE8)
demo3实例也是用于区分标准模式下ie6~ie9和Firefox / Chrome的hack,注意顺序
IE6显示为:红色,
IE7显示为:蓝色,
IE8显示为:绿色,
IE9显示为:粉色,
Firefox / Chrome显示为:橘色,
(本例IE10效果同IE9,Opera最新版效果也同IE9为粉色)
demo4实例是用于区分标准模式下ie6~ie10和Opera / Firefox / Chrome的hack,本例特别要注意顺序
IE6显示为:橘色,
IE7显示为:粉色,
IE8显示为:黄色,
IE9显示为:紫色,
IE10显示为:绿色,
Firefox显示为:蓝色,
Opera显示为:黑色,
Safari / Chrome显示为:灰色,
CSS hack方式三:选择器前缀法
选择器前缀法是针对一些页面表现不一致或者需要特殊对待的浏览器,在CSS选择器前加上一些只有某些特定浏览器才能识别的前缀进行破解。
目前最常见的是
* html *前缀只对IE6生效 * + html * +前缀只对IE7生效 @media screen \ 9 {...}只对IE6 / 7生效 @media \ 0screen {body {background:red; }}只对IE8有效 @media \ 0screen \,screen \ 9 {body {background:blue; }}只对IE6 / 7/8有效 @media screen \ 0 {body {background:green; 只对IE8 / 9/10有效 @media screen和(min-width:0 \ 0){body {background:grey; 对IE9 / 10有效 @media screen and(-ms-high-contrast:active),( - ms-high-contrast:none){body {background:orange; 对IE10有效 等等
结合CSS3的一些选择器,如HTML:第一胎,体:第n的式(1)中,衍生出更多的劈方式,具体的可以参考下表:
CSS3选择器结合的JavaScript的黑客
我们用IE10进行举例:
由于IE10用户代理字符串(UserAgent)为:Mozilla / 5.0(兼容; MSIE 10.0; Windows NT 6.2; Trident / 6.0),所以我们可以使用javascript将此属性添加到文档标签中,再运用CSS3基本选择器匹配。
JavaScript的代码:
var htmlObj = document.documentElement; htmlObj.setAttribute( '数据用户代理',navigator.userAgent的); htmlObj.setAttribute('data-platform',navigator.platform);
CSS3匹配代码:
html [data-useragent * ='MSIE 10.0'] #id { 颜色:#F00; }
CSS hack利弊
一般情况下,我们尽量避免使用CSS破解,但是有些情况为了顾及用户体验实现向下兼容,不得已才使用的黑客行为。比如由于IE8及以下版本不支持CSS3,而我们的项目页面使用了大量CSS3新属性在IE9 /火狐/ Chrome浏览器下正常渲染,这种情况下如果不使用css3pie或HTC或条件注释等方法时,可能就得让IE8-的专属黑客出马了。使用黑客虽然对页面表现的一致性有好处,但过多的滥用会造成HTML文档混乱不堪,增加管理和维护的负担。相信只要大家一起努力,少用,慎用破解,未来一定会促使浏览器厂商的标准越来越趋于统一,顺利过渡到标准浏览器的主流时代。抛弃那些陈旧的IE hack,必将减轻我们编码的复杂度,少做无用功。
最后补上一张引自国外某大牛总结的CSS hack表,这时一张6年前的旧知识汇总表了,放在这里仅供需要时候方便参考。
转载:《史上最全CSS Hack方式一览》