打印

KB003: CSS 解析错误的处理规则

作者:武利剑

CSS 句法( CSS Syntax )

语法1是语言表达的规则。各种语言都有不同的语法,包括人类语言和计算机语言等。

语法有时候也指句法( syntax ),指的是句子由词汇构成的规律。也可以将它看作组成句子的规则。它包含两个方面的涵义:

  • 词汇:即,可以构成句子的有效用词。例如,英语中的单词,JavaScript 中的 "var"、"for" 等等;
  • 规律:也可以将它看作规则,即,如何使用有效的词汇组成句子。比如,JavaScript 中要用 'var toolName;' 定义变量, 但是 Java 中却应该使用 'String toolName;' 等定义变量。 不同的语言,组成句子的规则不同。

CSS,同我们所认识的其他语言,例如 JavaScript 一样,有它自己的句法,适用于任何版本的 CSS。后续版本的应该坚持使用此核心句法,当然可以增加句法规则。

CSS 句法2描述了 CSS 的关键字、厂商扩展、可用字符集、规则集合、声明块、选择器、特性以及注释等所有 CSS 的构成部分。

如常用的 Class 选择器命名规范被定义为:

class : '.' IDENT

他由 '.' 字符开头,其后跟随 IDENT 规则。因此,根据断词书写规则检查 IDENT 书写规范如下:

Macro Definition
ident [-]?{nmstart}{nmchar}*
nmstart [_a-z]|{nonascii}|{escape}
nmchar [_a-z0-9-]|{nonascii}|{escape}
nonascii [^\0-\177]
escape {unicode}|\\[^\n\r\f0-9a-f]
unicode \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
nmstart [_a-z]|{nonascii}|{escape}
nmchar [_a-z0-9-]|{nonascii}|{escape}
nonascii [^\0-\177]
escape {unicode}|\\[^\n\r\f0-9a-f]
unicode \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?

对照表中内容可以组合出 Class 整体命名规范表达式为:

class : '.' [-]?([_a-z]|[^\0-\177]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?|\\[^\n\r\f0-9a-f])([_a-z0-9-]|[^\0-\177]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?|\\[^\n\r\f0-9a-f])*

注:

  1. 关于 语法 的更多信息,请参考 维基百科 - 语法
  2. 关于 CSS 句法的详细内容,请参考:W3C CSS2.1 - 4.1 Syntax
  3. 关于 CSS 书写断词规范,请参考: W3C CSS2.1 - 4.1.1 Tokenization 与 Appendix G. Grammar of CSS 2.1

CSS 解析错误

CSS 代码,可以看作是依照 CSS 句法所写的句子,而读这个句子的人,就是浏览器。因此,错误可能出自两个地方,一是不遵照 CSS 句法写代码的人, 一是不能正确解析 CSS 代码的浏览器。

在符合句法的情况下,一段 CSS 代码的解析,也可能在各个浏览器中都相同,但在不符合句法的时候,浏览器可能要加入自己的处理方式。正是因为浏览器的多样化, 才造成了对同一段 CSS 代码解析方式的多样化。

这里所讲的 CSS 解析错误,指的是,如果浏览器遇到不遵循句法(不合法)的 CSS 代码,会因无法正确的解析,而产生的错误。

某些不合句法的 CSS 错误,W3C 给出了确切的处理规则。

CSS 解析错误的处理规则

错误处理总则

对于不合法的 CSS 代码,浏览器需要忽略一部分不合法的样式表。

CSS2.1 及所有后继版本中,对于任何以破折号、下划线开头的 'property:value' 组合1和不包含标识符的 @-keywords 组合,都以忽略的方式处理。

分析以下代码:

div{
    _height: 19px;
    width:100px;
}

对于此类样式中的 '_height' 特性,浏览器应该以忽略的方式处理。经解析错误处理后的样式应该是:

div{
    _height: 19px;
    width:100px;
}

未知的特性( properties )

未知的特性,即属于以上所说不属于它句法中有效词汇的词汇。浏览器必须忽略带有未知特性的声明。

例:

div{
    yes:100px;
    width:100px;
}

其中,'yes' 不是 CSS 的特性,因此上述的声明 'yes:100px;' 应该被忽略。

不合法的值

不合法的值,也属于句法中无效的词汇。浏览器必须忽略带有不合法值的声明。

例:

div{
    height:100;
    width:100px;
}

'height' 特性的值2应该是一个数字后加一个单位构成的值。只有一个数字的值是不合法的,应当忽略3

畸形的声明

当浏览器解析一个声明时,读取它的代码直到这个声明的结束,同时,检查 (), [], {}, "", 和 '' 的匹配规则, 并且正确的处理编码,这时候,浏览器必须处理它所遇到的意外出现的标记。 怎样处理?标准没有明确指出。 因为针对不同的情况,应该采取不同的处理手段。

例:

p{height} /* 丢失了 ”:” 和后面的值,此属性应被忽略 */
({)P{width:100px}   /* 多余的  ({),此行应被忽略*/

这两条声明都是畸形的声明,应该被忽略。

不可用的 @ 关键字

本条类似于未知的特性。

例:

@google{
    height:100px;
    width:100px;
}

@google 不是标准中的 @ 关键字,声明应当被忽略。

样式表的意外结束

浏览器必须自动闭合敞开的结构(如,块,字符串和注解等)

例:

p{
    height:100px;
    width:100px;

缺少了闭合的大括号,浏览器应该自动补齐:

p{
    height:100px;
    width:100px;
}

字符串的意外结束

若值为字符串,却没有用单双引号闭合的情况。用户端应该在一行的结尾处,闭合字符串,一般都是以分号结尾。

例:

p {
    color: green;
    font-family: 'Courier New Times
    color: red;
    color: yellow;
}

以上代码相当于:

p {
    color: green;
    color: yellow;
}

以分号为界限,"font-family: 'Courier New Times color: red;" 这条声明中,‘font-family’ 的值不合法,应当被忽略。实际情况是,在 IE 中被忽略的是 "font-family: 'Courier New Times color: red; color: yellow;"

注:

  1. 比较具有讽刺意味的是,此类组合常被用于 IE 的 CSS hack,请参考:
  2. 关于特性的值,可参考: CSS 2.1 - 4.3 Values
  3. 此例子涉及到一个兼容性问题,请参考: W3Help - RY8002: 各浏览器对 CSS 代码及 CSS 相关 DOM 操作中长度 "<length>" 类型的值缺失单位的容错程度存在差异

引申阅读

相关浏览器对错误解析的处理引起的兼容性问题(容错),可以参考:

建议

虽然 W3C 明确规定了这些解析错误的处理规则,但各浏览器的处理还是不尽相同。而且,从上面的规则例子中可以看到,所有的错误都是人为的疏忽造成的,也有的是故意为之。 因此,为了更好的避免浏览器兼容性问题,一定要仔细检查,尽量不要出现 CSS 句法错误。

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6.8
Chrome 7.0.517.0 dev
Safari 5.02
Opera 10.62
测试页面:  
本文更新时间: 2010-09-15

关键字

CSS syntax Tokenization 错误解析 句法 书写规则 断词