首页 >web前端 >css教程 >CSS中的伪计算(或者如何浏览解析样式)

CSS中的伪计算(或者如何浏览解析样式)

William Shakespeare
William Shakespeare原创
2025-02-23 11:14:09603浏览

CSS伪注释 (或浏览器如何解析样式)

虽然CSS规范未提及,但您可以通过一些方法在CSS文件中模拟C风格和/或Unix风格的行注释(存在一些限制)。其他人之前也写过这方面的文章(特别是SitePoint的Web Foundations文章中涵盖了CSS注释)。本文将对此进行更详细的探讨。

关键要点

  • CSS正式只支持C风格的多行注释,但伪注释利用解析错误来无意中注释掉代码。
  • 伪注释可以通过使CSS声明格式错误来创建,例如省略分号或使用无法识别的属性名称,从而导致后续代码被忽略。
  • 伪注释的内联和下一行放置会影响后续CSS规则是否应用,内联伪注释可能会使同一行上的后续声明无效。
  • 伪注释也可以应用于@规则,根据@规则是否包含主体块或以分号结尾,观察到的行为会有所不同。
  • 虽然伪注释可用于调试,但它们可读性较差,不应在生产代码中替代标准CSS注释。

CSS注释

根据规范,CSS解析器正式支持一种注释样式,即来自C风格语言的多行注释,它使用起始标记/*和结束标记*/,如下所示:

<code>/*
  起始和结束标记之间(包括起始和结束标记)的字符将被解析器忽略,
*/</code>

因此,注释中的规则声明将被忽略:

<code>body {
  background: red;
  /*
  background: white;
  */
}</code>

注释中的块声明将被忽略:

<code>/*
body {
  background: red;
}
*/</code>

在这些示例中,我们都故意使用注释语法来指示解析器忽略内容。

但是,我们也可能意外地做到这一点,例如使用格式错误的声明:

<code>body {
  background: red    /* 缺少分号 */
  background: blue;      
}</code>

在此示例中,由于缺少分号,两个 background声明均未应用。解析器扫描下一个分号,确定整个两行语句格式错误,因此忽略整个词法分析的内容。如果我们完全省略属性值,也会发生同样的事情:

<code>body {
  background:
  background: blue; /* 此声明未应用 */
}</code>

表明我们可以使用格式错误的声明作为……

伪注释

我们将这些称为“伪注释”,因为严格来说,这些不是在行尾字符处终止的注释。相反,它们通过使后续输入(甚至在后续行)格式错误来工作。这是由于规则集、声明块和选择器的错误处理过程:

“如果选择器中的任何位置出现错误,则应忽略整个语句,即使选择器的其余部分在CSS 2.1中看起来合理。”

在以下示例(摘自规范)中,由于选择器中存在无效字符“&”,第二个规则集被忽略:

<code>h1, h2 {color: green }
h3, h4 & h5 {color: red } /* h6 {color: black }</code>

同样,在以下示例中,由于在background属性名称中存在多余字符,第二个和第三个声明被忽略:

<code>body {
  background: red;
  xbackground: white;    /* 属性名称未被识别 */
  y background: blue;    /* 属性名称格式不正确 */
}</code>

快速浏览一下英语键盘,就会发现以下特殊字符将充当单行声明注释:

<code>/*
  起始和结束标记之间(包括起始和结束标记)的字符将被解析器忽略,
*/</code>

但是,不要使用任何字符,而应坚持使用C和Unix约定,并使用#或//:

<code>body {
  background: red;
  /*
  background: white;
  */
}</code>

分号

分号是规则声明的结束标记。因此,它们不能“注释”其后的文本。用规范的话说,解析器将悬空分号视为格式错误的声明(缺少名称、冒号或值的声明)。

如前所述,当常规多行注释格式错误时,即起始和结束标记未围绕规则集或声明平衡时,解析器会忽略后续的声明或规则集。以下内容实际上将“注释”掉两个 background声明,因为解析器将搜索受影响声明的下一个声明结束标记(分号):

<code>/*
body {
  background: red;
}
*/</code>

通过在注释后、下一个声明前添加分号来修复此问题(因此将应用background blue声明):

<code>body {
  background: red    /* 缺少分号 */
  background: blue;      
}</code>

对于一行缺少分号的伪注释,效果相同:

<code>body {
  background:
  background: blue; /* 此声明未应用 */
}</code>

并通过恢复分号来更正:

<code>h1, h2 {color: green }
h3, h4 & h5 {color: red } /* h6 {color: black }</code>

内联与下一行放置

这就是“伪”进入“伪注释”一词的地方。这可能是根本不称其为“注释”的充分理由,因为它们违背了C或Unix风格行注释的行尾约定。

放在自己一行上的伪注释将抑制下一行上的声明。在以下示例中,background将为蓝色:

<code>body {
  background: red;
  xbackground: white;    /* 属性名称未被识别 */
  y background: blue;    /* 属性名称格式不正确 */
}</code>

放在同一行有效声明之后的伪注释将抑制下一行上的声明。在以下示例中,background将为白色而不是蓝色:

<code>selector {
  ~ property-name: ignored;
  ` property-name: ignored;
  ! property-name: ignored;
  @ property-name: ignored;
  # property-name: ignored;
  $ property-name: ignored;
  % property-name: ignored;
  ^ property-name: ignored;
  & property-name: ignored;
  * property-name: ignored;
  _ property-name: ignored;
  - property-name: ignored;
  + property-name: ignored;
  = property-name: ignored;
  | property-name: ignored;
  \ property-name: ignored;
  : property-name: ignored;
  property-name: ignored;
  . property-name: ignored;
  > property-name: ignored;
  , property-name: ignored;
  ? property-name: ignored;
  / property-name: ignored;
}</code>

即使是带有内联伪注释的CSS选择器的“压缩”版本也将表现为单声明注释。在以下示例中,由于解析器识别到的注释标记#在下一个分号处终止,第一个background声明被忽略,第二个background声明被识别为格式正确,因此被应用(在这种情况下,蓝色将应用于body background):

<code>// background: ignored;
  # background: ignored;</code>

(后续内容同理,由于篇幅限制,此处省略剩余部分的伪原创。)

以上是CSS中的伪计算(或者如何浏览解析样式)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn