清理插值
Natalie Weizenbaum 于 2015 年 12 月 9 日发布
插值——使用 #{...}
添加变量和其他代码片段的能力——是 Sass 最方便的多功能特性之一。您几乎可以在任何需要注入变量、函数调用或其他表达式的任何地方使用它。在大多数情况下,它只是将值插入到周围的文本中。它简单易懂且实用,这正是我们对一个 特性所期望的。
不幸的是,这仅在大多数情况下为真。由于复杂的历史原因,插值在一个地方有点疯狂:表达式内部但引号外部。大多数时候,它是有意义的;如果您编写 display: -#{$prefix}-box
,您将获得预期结果。但是,如果在插值旁边使用了 +
等任何运算符,您将开始获得奇怪的输出。例如,$name + #{$counter + 1}
可能会返回一个包含文本 name + 3
的未加引号的字符串。
这是一种非常奇怪的行为。为什么 +
在这里表现得与其他地方不同?为什么在 $name
正常计算时将其视为纯文本?这种行为令人困惑、不一致且不太实用,这些是我们绝对不希望在特性中看到的。那么它们为什么一开始就存在呢?
复杂的历史原因复杂的历史原因 永久链接
如果您不想听历史课,请跳到崭新世界 。
早在远古时代,当缩进语法是唯一语法时,Sass 区分了“静态”和“动态”属性。静态属性基本上是纯 CSS;它使用 property: value
声明,并且该值按原样使用,无需任何进一步处理。如果您想使用变量或函数,则必须使用动态属性,该属性使用 property= value
声明。您会看到很多这样的样式表
.border
border-width: 4px
border-style: solid
border-color= !background_color
此外,在远古时代,变量使用 !
而不是 $
,并且不能包含连字符。远古时代有点糟糕。但在这种情况下,我们首次添加了插值。我们希望允许具有多个值的属性(如 border
)部分动态,因此我们决定效仿 Ruby 的做法,允许使用 #{}
插入值。很快,样式表开始如下所示
.border
border: 4px solid #{!background_color}
好多了!有一段时间,一切都 平静。
然后来了 SCSS然后来了 SCSS 永久链接
最终变得很明显,用户确实非常希望他们的样式表看起来像 CSS,因此我们坐下来开始着手开发将在 Sass 3 的版本中成为 SCSS 的语法。作为这项工作的一部分,我们决定完全取消静态和动态属性之间的区别。让所有属性都以相同的方式工作显然对用户来说很棒,但这意味着我们必须弄清楚如何在最大程度地减少 痛苦的情况下合并这两个语法。
这在很大程度上是简单的,因为旧的表达式语法几乎普遍是无效的 CSS 或无论如何都会发出其 CSS 值的内容。但插值被证明很棘手。向后兼容性对我们来说非常重要,因此我们希望确保 Sass 2 中使用(或理论上可能使用)插值的所有位置都将在 Sass 3 中继续工作,即使它们周围的一切现在都被完全解析了
我们的解决方案是使 #{}
周围基本上任何明显不属于纯 CSS 表达式的内容都变成字符串。这样,希望人们遇到的任何奇怪的极端情况在他们升级时都能继续工作。这导致了我在上面描述的奇怪行为,但在当时,我们的首要任务是尽可能轻松地让用户迁移到 Sass 3。我们认为这种奇怪之处是值得的,并将其发布了
崭新世界崭新世界 永久链接
快进到今天。我们现在开始着手下一个主要版本 Sass 4 的工作,而且(我非常希望)多年来没有人再编写过任何 Sass 2 样式表。主要版本是一个清理这段历史遗留代码的好机会,并且在在问题跟踪器上广泛讨论之后,我们决定进行 更改。
像这样向后不兼容的更改包含三个主要步骤。第一步是设计新的语法,这里非常简单,因为它基本上就是“做每个人之前认为它已经做的事情”。我们只需要采用这个普遍的概念并找出 细节。
我们最终将其构建为 #{}
在语法上是标识符的一部分。当您编写 -#{$prefix}-box
时,Sass 会将其解析为一个包含 "-"
后跟 $prefix
的值后跟 "-box"
的单个标识符。即使您单独编写 #{$font}
,它也会被解析为一个仅包含 $font
值的标识符。这样,插值在运算符周围不再具有奇怪的行为,就像标识符从未 有过一样。
一旦我们有了设计,第二步就是弃用旧的行为。弃用的核心是确定何时打印警告,而这里却非常困难。我们不想对即使涉及运算符也会继续工作的场景发出警告——例如,12px/#{$line-height}
将在旧世界和新世界中打印正确的内容(尽管原因略有不同),但 12px+#{$line-height}
则不会。
我不会详细介绍我们如何使弃用在这里生效;这就是GitHub 问题的用途。需要说明的是,它涉及许多特殊情况,包括一些根据值的使用方式而不是编写方式打印弃用警告的情况。不过,我对最终结果非常满意;我怀疑它将捕获 99% 的实际会中断的案例
另一个令人兴奋的额外好处是能够自动更新代码。在引入向后不兼容性时,这并不总是有效,但在这种情况下,我们能够使 sass-convert
将插值的弃用用法转换为与 Sass 4 兼容的代码。它有一些误报——它仅转换可以证明不兼容的案例——但这足以让用户走很远
弃用到位后,最后一步是移至main
分支(最终将成为 Sass 4),删除所有旧行为,并实现新行为。而且它太棒了。删除糟糕的代码并用干净的东西替换它,感觉就像在炎热阳光下穿过灰尘徒步旅行一天后洗了个澡一样。在处理这个特性几个星期后,我很高兴看到它的另一端
查看查看 永久链接
今天发布的 Sass 3.4.20 是第一个包含旧语法弃用警告的版本。如果您想检查您的样式表中是否有任何弃用的插值潜伏,只需 gem install sass
并重新编译您的样式表即可。如果您确实找到了一些,请尝试运行 sass-convert --recursive --in-place .
以自动修复大量
如果您想尝试新语法,今天也发布了 4.0.0.alpha.1。您可以使用 gem install sass --prerelease
获取它。但请注意:它是 alpha 软件,因此将来可能会发生变化。我们通常会尝试使我们的预发布版本保持稳定,但您也有可能遇到 错误。
如果您确实发现了错误,请在问题跟踪器上提交它。即使是简单的错别字,我们也想知道。如果我们弃用了应该有效的某些内容,我们尤其想知道。如果您只是有疑问,请随时在 @SassCSS 上发推文或在邮件列表 上发布。