意见征集:一等公民 Calc

2021年3月15日发布,作者 Natalie Weizenbaum

Sass 中最受用户请求的功能之一就是能够更轻松地处理 calc() 表达式。这些表达式历来都被不透明地解析:在括号之间,您可以放置任何文本,Sass 会将其视为未加引号的字符串。这简化了 Sass 的解析器,因为我们不必支持特定的 calc() 微语法,并且这意味着我们自动支持新功能,例如在 calc() 中使用CSS 变量

但是,这也带来了巨大的可用性成本。因为每个 calc() 对 Sass 的解析器都是完全不透明的,所以用户不能简单地使用 Sass 变量来代替值;他们必须显式地插值变量。并且一旦创建了 calc() 表达式,就无法像操作普通数字一样使用 Sass 来操作它。

我们希望通过一个名为“一等公民 Calc”的新提案来改变这一点。此提案将 calc()(以及其他受支持的数学函数)从解析为未加引号的字符串更改为深入解析,有时(尽管并非总是)会生成一种称为“计算”的新数据类型。此数据类型表示在编译时无法解析的数学表达式,例如 calc(10% + 5px),并允许这些表达式在进一步的数学函数中优雅地组合。

更具体地说:calc() 表达式将根据CSS 语法进行解析,并额外支持 Sass 变量、函数以及(为了向后兼容)插值。Sass 会在编译时尽可能多地执行数学运算,如果结果是单个数字,则将其作为普通的 Sass 数字类型返回。否则,它将返回一个表示可以在浏览器中解析的(简化)表达式的计算。

例如

  • calc(1px + 10px) 将返回数字 11px

  • 类似地,如果 $length10px,则 calc(1px + $length) 将返回 11px

  • 但是,calc(1px + 10%) 将返回 calc calc(1px + 10%)

  • 如果 $lengthcalc(1px + 10%),则 calc(1px + $length) 将返回 calc(2px + 10%)

  • Sass 函数可以直接在 calc() 中使用,因此 calc(1% + math.round(15.3px)) 返回 calc(1% + 15px)

请注意,计算通常不能替代数字。例如,1px + calc(1px + 10%) 将产生错误,math.round(calc(1px + 10%)) 也会产生错误。这是因为计算不能与数字互换使用(您不能将计算传递给 math.sqrt()),因此我们希望确保数学函数明确说明它们是否支持计算,方法是将所有数学运算都包装在 calc() 中或使用普通的 Sass 算术运算。

为了向后兼容,包含插值的 calc() 表达式将继续使用旧的、高度宽容的语法进行解析,尽管此行为最终将被弃用并删除。这些表达式仍将返回计算值,但它们永远不会被简化或解析为普通数字。

请告诉我们您的想法!请告诉我们您的想法! 永久链接

如果您有兴趣了解更多关于此提案的信息,请在 GitHub 上完整阅读。它将在未来一个月内开放评论和修订,因此如果您想看到某些更改,请提交问题,我们可以讨论一下!