打印

RY8003: 各浏览器对 CSS 错误解析规则的差异及 CSS hack

作者:武利剑 陆远 杨稍辉

标准参考

问题描述

各浏览器对 CSS 错误解析规则的差异。

造成的影响

CSS 错误解析规则的差异会导致在不同浏览器中达不到预期的效果。

受影响的浏览器

所有浏览器  

问题分析

CSS 语法适用于任何版本的 CSS,它描述了 CSS 的核心句法 (syntax)、关键字、厂商扩展、可用字符集、规则集合、声明块、选择器、特性以及注释等所有 CSS 的构成部分。

CSS 语法规定了 CSS 的写法,但是开发人员还是可能写出不合 CSS 语法的代码,这时候,浏览器就需要忽略一部分不合法的样式表。CSS2.1 及所有后继版本中,对于任何以破折号、下划线开头的 property:value 组合和不包含标识符的 @-keywords 组合,都以忽略的方式处理。

为了保证新的属性和值可以被正确添加,但遇到以下情况时,浏览器必须遵循以下的规则:

  1. 未知的属性。浏览器必须忽略带有未知属性的声明。如,p { yes:'good' }
  2. 不合法的值。浏览器必须忽略带有不合法值的声明。如,p { height:20 }
  3. 畸形的声明。当浏览器解析一个声明时,读取它的代码直到这个声明的结束,同时,检查 (), [], {}, "", 和 '' 的匹配规则,并且正确的处理编码,这时候,浏览器必须处理它所遇到的意外出现的标记。 如,p { height }或 ( { )P { width:100px }
  4. 不可用的 @ 关键字。如:@hello {...}
  5. 样式表的意外结束。浏览器必须自动闭合敞开的结构 (如,块,字符串和注解等) 如 @media screen { p:before { content: 'Hello
  6. 字符串的意外结束。如, p { color: green; font-family: 'Courier New Times color: red; color: green; }

因为各大厂商对标准的实现不尽相同,所以,不同浏览器对CSS代码的解析标准不同。因此,对相同的 CSS 代码,各浏览器的解析可能会有差异。而在此差异的基础上,写出的只有个别浏览器或某些浏览器识别的 CSS 代码,就形成了 CSS hack 。

 

浏览器对 CSS 错误解析规则的差异

1. 畸形的声明

(1). 多余的右大括号:.pink { background:pink;} }。在 IE5 IE5.5 IE6 IE7 IE8(Q) 下可自动修复。

(2). 未闭合的左大括号:.pink { background:pink; /*大括号没有闭合*/。在 IE5 IE5.5 IE6(Q) IE7(Q) IE8(Q) 下,未闭合的左大括号把下一个声明的右大括号当作了闭合括号。

(3). 多余的左括号——情况1:左括号位于选择器之后:.pink { { background:pink; }。在 IE5 IE5.5 IE6 IE7 IE8(Q)下,浏览器直接忽略了多余的左大括号 "{" 。

多余的左括号——情况2:左括号位于选择器之前:{.pink { background:pink; }。在 IE5 IE5.5 IE6 IE7(Q) IE8(Q) 下,浏览器将多余的左大括号 "{" 与其后的选择器合并。

(4). 属性和值由等号连接:.pink { background=pink; color=blue; font-size=28px; }。在IE5 IE5.5 IE6(Q) IE7(Q) IE8(Q) 下,浏览器直接将错误的等号替换为了正确的冒号。

(5). 空的特性值:background:pink; background:;。在 IE6 IE7 IE8(Q) 下, 浏览器将没有值的 "background:" 替换了之前的 "background:pink;" ,而由于值为空,所以使用默认样式值渲染。

(6). 选择器与 "{" 之间出现多余 "," :.pink, { background:pink; }。在 IE6 IE7 IE8(Q) 下,浏览器将选择器后多余的逗号忽略。

(7). 选择器之前出现分号:;.pink { background:pink; } ;。在 IE6 IE7 IE8(Q)下,浏览器将选择器前多余的分号忽略。

(8). 选择器之前出现多余的".":...pink { background:pink; } ..gold { background:gold; }。在 IE6 IE7(Q) IE8(Q) 下,浏览器将选择器前多余的点忽略。

2. 不合法的属性值

(1). 属性值对之间没有分号:.pink { background:pink color:blue font-size:28px }。在 IE5 IE5.5 IE6(Q) IE7(Q) IE8(Q) 下,浏览器会正确解释缺失的第一个分号之前的声明 'background:pink' 被正确的解释及渲染。

(2).使用 !important,且声明之间缺失分号:.pink { background:pink !important color:blue !important font-size:28px }。在 IE5.5 IE6(Q) IE7(Q) IE8(Q) 下, 浏览器会正确解释所有声明。

(3). 长度值缺失单位:.pink {background:pink; font-size:28; height:50;}。在 IE5 IE5.5 其他各浏览器的混杂模式下, 浏览器会为缺失 px 的属性值添加 "px" 以正确解释其含义。

3. 其他

(1). HTML标签 "style" 属性内出现多余大括号:<div style="{background:pink;}">background:pink</div>。在IE5 IE5.5 IE6 IE7 IE8(Q) Firefox(Q) Opera(Q) 下, 浏览器会忽略 "style" 属性中最外层多余的一对大括号。

(2). 注释前出现多余字符:在 IE6 IE7 IE8(Q) 下, 浏览器直接忽略 "<!--" 之前多余的字符。

 

CSS hack

由于不同的浏览器,比如 IE6 IE7 IE8 Firefox 等,对 CSS 解析的标准不同,因此对于相同的 CSS 代码,可能会生成不同的页面效果,从而无法在所有浏览器中得到我们想要的效果。这时,我们就需要针对不同的浏览器去写不同的 CSS 代码,让它能够在所有浏览器中获得相同的效果。这个过程,就是 CSS hack 。也就是上面说到的: "写出只有个别浏览器或某些浏览器识别的 CSS 代码" 。

CSS hack 是因为现有浏览器对标准的解析不同,为了兼容各浏览器,所采用的一种补救方法。CSS hack 是 一种类似作弊的手段,以欺骗浏览器的方式达到兼容的目的,是用浏览器的兼容性差异来解决浏览器的兼容性问题。

因此,在设计之初,写 CSS hack 需要遵循以下三条原则:

  • 有效: 能够通过 Web 标准的验证
  • 只针对太古老的/不再开发的/已被抛弃的浏览器, 而不是目前的主流浏览器
  • 代码要丑陋。让人记住这是一个不得已而为之的 Hack, 时刻记住要想办法去掉它。

现在很多 hacks 已经抛弃了最初的原则。滥用 hack 会导致浏览器更新之后产生更多的兼容性问题。因此,并不推荐使用 CSS hack 来解决兼容性问题。

CSS hack 的实现方式

  1. 利用浏览器对相同代码的解析和支持的不同实现的 hack
  2. 以 Firefox 或 Webkit 特有的扩展样式实现的 hack
  3. 利用 IE 对标准的支持缺陷写的 hack
  4. 以 IE 特有的条件注释为基础的 hack

Windows 系统下 CSS hack 汇总表

  IE6 IE7 IE8 FF Ch Sa Op
  Q S Q S Q S Q S Q S Q S Q S
*+html selector N N N Y N N N N N N N N N N
*html selector Y Y Y N Y N N N N N N N N N
_property:value Y Y Y N Y N N N N N N N N N
-property:value Y Y N N N N N N N N N N N N
html* selector Y Y Y Y Y N N N N N N N N N
*property:value Y Y Y Y Y N N N N N N N N N
operty:value\9 Y Y Y Y Y Y N N N N N N N N
selector, x:-moz-any-link{...} N N Y Y Y N Y Y N N N N N N
selector, x:-moz-any-link, x:default{...} N N Y Y Y N Y Y N N N N N N
@-moz-document url-prefix(){...} N N N N N N Y Y N N N N N N
html>/**/body selector, x:-moz-any-link N N N N N N Y Y N N N N N N
html>/**/body selector, x:-moz-any-link, x:default{...} N N N N N N Y Y N N N N N N
以-moz开头的Firefox特有扩展样式 N N N N N N Y Y N N N N N N
@media screen and (-webkit-min-device-pixel-ratio:0) {...  } N N N N N N N N Y Y Y Y N N
以-webkit开头的Webkit浏览器特有扩展样式 N N N N N N N N Y Y Y Y N N
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0){...} N N N N N N N N N N N N Y Y

解决方案

合理运用各浏览器对 CSS 错误解析规则的差异及 CSS hack 为不同浏览器赋予不同样式。

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.5.5
Chrome 4.0.249.22
Safari 4.0.4
Opera 10.51
测试页面:  
本文更新时间: 2010-07-19

关键字

CSS hack 识别浏览器 bug IE6 IE7 IE8 Firefox Webkit