Less.js: 内置函数中的自定义属性,如 `rgba()` 抛出错误

创建于 2016-11-13  ·  14评论  ·  资料来源: less/less.js

CSS 自定义属性内容的语法非常宽松,但是在rgba()等内置函数中使用此类属性时会出现问题

例子:
我的项目允许用户定义整个应用程序 UI 和各种自定义组件所基于的强调色。 我使用 rgb 格式是因为需要在某些地方淡入淡出,而 CSS 没有提供类似fade(<strong i="8">@color</strong>, 50%)任何东西。 这样我就可以做到rgba( var(--color), 0.5 ) 。 这适用于 Chrome,并受标准支持。 但是 less 会引发以下错误error evaluation function 'rgba': color functions take numbers as parameters

示例代码:

:root {
    --color-accent: 169,57,255;
}
button:hover {
    background-color: rgba(var(--color-accent), 0.2);
    color: rgb(var(--color-accent));
}

注意:这是一个嵌入式库,我不想强​​迫用户在他们的工作流程中添加另一个构建步骤,只是为了使用他们的颜色构建我的 less 库。 这就是为什么我使用新的和闪亮的自定义属性(也因为它的作用域能力)。

顺便说一句:是否有一些临时解决方法可以跳过如此严格的处理并无论如何都要构建它? 这不像我在嵌套规则中缺少括号。

feature request high priority

最有用的评论

CSS 自定义属性内容的语法非常宽松,但是在rgba()等内置函数中使用此类属性时会出现问题

例子:
我的项目允许用户定义整个应用程序 UI 和各种自定义组件所基于的强调色。 我使用 rgb 格式是因为需要在某些地方淡入淡出,而 CSS 没有提供类似fade(<strong i="9">@color</strong>, 50%)任何东西。 这样我就可以做到rgba( var(--color), 0.5 ) 。 这适用于 Chrome,并受标准支持。 但是 less 会引发以下错误error evaluation function 'rgba': color functions take numbers as parameters

示例代码:

:root {
  --color-accent: 169,57,255;
}
button:hover {
  background-color: rgba(var(--color-accent), 0.2);
  color: rgb(var(--color-accent));
}

注意:这是一个嵌入式库,我不想强​​迫用户在他们的工作流程中添加另一个构建步骤,只是为了使用他们的颜色构建我的 less 库。 这就是为什么我使用新的和闪亮的自定义属性(也因为它的作用域能力)。

顺便说一句:是否有一些临时解决方法可以跳过如此严格的处理并无论如何都要构建它? 这不像我在嵌套规则中缺少括号。

这样写~

:root {
    --color-accent: 169,57,255;
}
button:hover {
    background-color: ~"rgba(var(--color-accent), 0.2)";
    color: ~"rgb(var(--color-accent))";
}

所有14条评论

逃吧


我放置了“功能请求”标签,因为当自定义属性在 TR 中时它肯定会成为一个问题。 通过禁用 CSS 函数 args 的任何错误检测很容易修复(尽管这很遗憾,因为它杀死了语言的一个重要部分 - 即在浏览器中调试之前我们永远不会发现错误)。

自定义属性支持除 IE11 之外的所有浏览器。 它们可能会在明年成为主流,所以我认为应该尽快实施支持。

更少,AFAIK,也没有对自定义属性值的极端宽容性质进行测试。 它们几乎可以包含任何内容,甚至是分号,只要它们不是顶级标记(不包含在括号或花括号对中)。 请参阅: https :

由于此更改无论如何都需要 n-of-args 检查(以在函数中至少保留一些错误验证),因此还假设较新的rgba实现也支持序数颜色值的两个参数形式,例如:

rgba(var(--some), .42); // -> rgba(var(--some), .42)
rgba(#010101, .42); // -> rgba(1, 1, 1, .42)

通常我们应该如何处理 args 中的自定义属性? 从技术上讲,您几乎可以在任何地方使用var(--some-property) ,如果 Less 试图解释诸如rgba()类的内置 CSS 函数的参数,那就是一个问题。 虽然我不确定为什么 Less 会为内置 CSS 函数抛出严格的值错误? 只是为了支持表达式?

我在https://github.com/less/less.js/blob/master/lib/less/functions/color.js#L34看到一大堆内置的 CSS 函数,而 IMO 大部分不应该在那里。 Less 不是 linter,那些也不是 Less 函数。 如果解析器试图在 CSS 函数上变得非常聪明,它就会失败。 所以我认为这就是问题的根源,Less 目前正在修补常规 CSS 颜色函数,而不是让它们通过。

我不确定是否为尚不支持rgb() rgba()浏览器添加了它? 好像是 4 年前添加的。 也许是为了平衡浏览器尚不支持的较新颜色功能? 🤔 @lukeapage你还在回答吗?

考虑到我在 #3214 的评论,对于这个问题,快速修复将只是:“if (nargs < 3/4) 回退到 css 字符串(通过不返回任何内容)”在相应的函数实现中。

(更严格的修复是检查每个此类 func 中的每个 arg 以确定它是否可评估并返回颜色对象或 CSS 字符串后备)。

考虑到我在 #3214 的评论,对于这个问题,快速修复将只是:“if (nargs < 3/4) 回退到 css 字符串(通过不返回任何内容)”在相应的函数实现中。

var()的类似支票?

darken(rgba(var(--red-value), 2, 3, .4), 5%)

那就是:我们是否应该做以下事情:

  1. 如果函数与 n-args 不匹配,是否允许传递函数? 我假设我们需要特别标记函数,因为函数注册表没有什么特别之处(除非我们做一些像toString()这样疯狂的事情,并且用正则表达式字面上计算参数——AFAIK 是 JS 中唯一的反射类型;你也许可以用 TypeScript 做到这一点,但这对我们没有帮助)
  2. 如果在另一个 Less 函数评估中使用了不匹配的函数,则抛出错误。

这是一个有趣的问题,因为自定义属性的引入使得 CSS 函数在编译时无法解析。 在某种程度上,我们可能正处于静态预处理时代的末期。 但这是一个完全不同的讨论。

这是一个有趣的问题,因为自定义属性的引入使得 CSS 函数在编译时无法解析。

真的没有什么新鲜事。 从 v1.x 开始,所有使用 Less 处理此问题的必要工具都已存在 - 见下文。 唯一的挑战是以不臃肿的方式对其进行编码。

我认为我们需要特别标记函数,因为函数注册表没有什么特别之处

不,如果函数发现它们无法评估它们的参数,它们应该只返回undefined (或null ):像这样(除非它们也检测到 args 是 100% 不稳定的,并且最好触发错误)。 .
未定义的返回值使函数评估器回退到初始字符串表示形式: Demo

var()的类似支票

也不,没有必要检查var或任何特定的东西(基本上是 CSS 未来的未知事物)。 这才是重点。 代码应该检查哪些是可以评估的(已知事物),而不是哪些是无法评估的(未知)。
(虽然细节可能非常依赖于特定的功能——这并不重要)。


顺便说一句,请注意--var也是一个内置的 Less 函数(以及任何ident(...)东西),只是没有显式实现(因此它只是回退到自我字符串表示) 因为没有必要这样做。 但是插件(例如)可能会用自己的实现覆盖它,这可能会返回潜在的可评估值。

@seven-phases-max 哦,好吧,所以您认为简单的解决方法是让这些 CSS/Less 函数返回 undefined 而不是抛出错误(按原样呈现)? 这似乎是合理的,那么如果功能没有。 2(如darken() )无法解释 arg (此时会被评估为rgba()匿名值?),它仍然应该抛出?

与自己争论:

也不,没有必要检查var()或任何特定的东西(基本上是 CSS 未来的未知事物)。

另一方面,专门检测var以便函数可以区分rgba(var(...), ...)rgba(foo, ...)并且仍然触发错误不是问题(甚至诱人)对于后者,但这意味着每次他们向 CSS 添加新内容时都会提出类似的问题。
(我猜这两种变体都很好,更多的是寻找平衡和/或预测维护者的负担更轻......)。

@马修院长

这似乎是合理的,那么如果功能没有。 2(如darken())不能解释一个arg(此时它会被评估为一个rgba()匿名值?),它仍然应该抛出?

是的,确切地说 - 我们甚至不需要任何新代码(尽管理想情况下它们(像darken这样的函数)在这种情况下应该有更友好的错误消息,因为当前的"a.toHSL is not a function" -like 消息是相当混乱)。

好吧,另一件没有提到的事情是浏览器将rgba(calc(1),1,1)类的东西视为有效(注意 calc 和 3 vs. 4 参数),所以我们可能不应该太聪明。 如果可能的话,我喜欢按一般规则输出的想法。

是的,这就是我的意思

代码应该检查哪些是可以评估的(已知事物),而不是哪些是无法评估的(未知)。

Less rgba的唯一有效参数是数字或颜色对象(如果我们还考虑类似“neo”-“CSS4”的形式,如rgba(#123, .42) )。
其他任何东西要么是错误,要么是(未知但可能有效)CSS 值。

CSS 自定义属性内容的语法非常宽松,但是在rgba()等内置函数中使用此类属性时会出现问题

例子:
我的项目允许用户定义整个应用程序 UI 和各种自定义组件所基于的强调色。 我使用 rgb 格式是因为需要在某些地方淡入淡出,而 CSS 没有提供类似fade(<strong i="9">@color</strong>, 50%)任何东西。 这样我就可以做到rgba( var(--color), 0.5 ) 。 这适用于 Chrome,并受标准支持。 但是 less 会引发以下错误error evaluation function 'rgba': color functions take numbers as parameters

示例代码:

:root {
  --color-accent: 169,57,255;
}
button:hover {
  background-color: rgba(var(--color-accent), 0.2);
  color: rgb(var(--color-accent));
}

注意:这是一个嵌入式库,我不想强​​迫用户在他们的工作流程中添加另一个构建步骤,只是为了使用他们的颜色构建我的 less 库。 这就是为什么我使用新的和闪亮的自定义属性(也因为它的作用域能力)。

顺便说一句:是否有一些临时解决方法可以跳过如此严格的处理并无论如何都要构建它? 这不像我在嵌套规则中缺少括号。

这样写~

:root {
    --color-accent: 169,57,255;
}
button:hover {
    background-color: ~"rgba(var(--color-accent), 0.2)";
    color: ~"rgb(var(--color-accent))";
}

@weivea在最新版本的Less 3.x 上,这个没必要,直接写rgba(var(--color-accent))

此页面是否有帮助?
0 / 5 - 0 等级