Less.js: 如何处理数学

创建于 2014-02-17  ·  102评论  ·  资料来源: less/less.js

  1. 我们决定采用严格的数学方法,但人们普遍担心在每次计算中都使用 ()
  2. 我认为我们不想大规模改变事情或回到绘图板

见#1872

是否可以为 calc 添加另一种情况,例如字体,关闭严格模式,基本上为规则打开严格模式? 未来有太多例外?

@seven-phases-max :
嗯,还有很多其他的可能性,例如./或需要括号进行除法(例如1/2 -> 1/2(1/2) -> 0.5 ) 等...
此外,“特殊情况”(例如x/y可以作为速记出现的属性)并不罕见(从padding / margin开始,以background结尾) border-radius最终可以有更多)所以我们不能像font那样对它们进行硬编码(因此我认为当前的字体“解决方法”只是临时且相当脏的杂物,理想情况下也应去除)。

feature request high priority

最有用的评论

为了简化/重申提案- 数学变化如下

  1. 加法和减法只会在相同的单位上计算。 例如1px + 2px = 3px , 1px + 1vh = 1px + 1vh
  2. 除法和乘法只能用无单位的除数/乘数计算。 例如10px/2 = 5px , 10px/5px = 10px/5px
  3. 没有单位的价值比率将类似于#2。例如1/3 = 1/3
  4. 为简化起见,可以将带有部分无效子表达式的表达式视为无效的数学表达式并按原样输出。 例如1px + 2vh / 2 = 1px + 2vh / 2

该提案解决了以下问题(来自该线程):

  • font: 10px/5px和类似(ratio)语法(无计算)
  • calc(100vh - 30px) (不计算)
  • lost-column: 1/3和类似的自定义比率语法(无计算)

同时,这些更改将保留 99% 的典型 Less 数学用法。 同样,现有的unit()convert()函数允许用户将值转换为兼容的数学单位。

所有102条评论

我认为我们不想大规模改变事情或回到绘图板

是的,我建议开始这个只是因为 _if_ 我们想要在 3.0 中使用一些“默认”严格数学,我们将不得不发明一些比当前更轻的东西(并且有可能在不引入任何新的--alt-strict-math情况下解决所有问题font类似硬编码解决方案背后隐藏的问题......)。

我没有意识到它的成长

https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius

:(

我认为目前我赞成最初将 strictMaths 扩展为

  • 离开
  • 分配

然后对于 2.0.0 设置默认为 Division

所以..

媒体查询 - 如果关闭,则切换到子节点的划分
字体 - 如果关闭,则切换到子节点的分割
calc( - 如果关闭或除法,打开子节点

https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius

是的,我认为他们倾向于在 _any_“shorhand property”中允许“shorthand values”(即x/y )......

相关: https :

另一种选择.. 处理 calc 调用,但仅限于单位使其成为可能的地方,例如
计算( 1% + 2%) => 3%
calc(100% - 10 px) => 不变

这将修复calc但不会修复 #1627 和相关内容。
我的意思是, calc(100% - 10 px) => unchanged可能是calc的解决方案,但这并不能取消对less-heavy-than-parens-everywhere解决方案的需求。

如果重新审视严格的数学,我想建议像percentage()这样的 Less 函数不需要在它们内部添加额外的括号。 随着严格的数学计算,你必须双重包装参数。 这将大大减少混淆和难以发现的错误的可能性,因为percentage(16 / 17)percentage((16 / 17))都是有效的。

@calvinjuarez V2提供了一个插件子系统,插件可以在其中向环境添加任意数量的函数,从这个意义上说,核心将无法决定此类内置函数是否需要单个值或表达式,即它是允许接受16/17 ,然后评估16/17 _before_ 它被传递给一个函数是不正确的(好吧,粗略地说 - 它比内部复杂一些)。

在这种情况下, ./变化似乎是我最喜欢的,尽管我知道这将是非常戏剧性的变化(如果与(/) ,不计算它在.之前也需要一个空格,例如16 ./17而不是16./17 ,嗯)。

目前较少破坏有效 css 的另一件事是背景速记:

background: url(image.png) 50%/300px no-repeat;

我认为目前我赞成最初将 strictMaths 扩展为

离开
分配

然后对于 2.0.0 设置默认为 Division

抱歉,我在 2.0 发布之前没有对此做出回应。 我认为这是一种很好的直觉。 裸除法运算符只是与太多的 CSS 冲突,并且随着人们使用更多 CSS3 特性,冲突会越来越多。 而且我理解人们反对所有数学都不需要括号,因为在许多情况下不需要它。

@七阶段最大

允许接受 16/17,然后在将 16/17 传递给函数之前评估 16/17 将是不正确的

严格来说,是的,这是完全正确的。 这不应该在它到达函数之前评估,特别是对于自定义函数。 但是,我认为允许函数选择处理这样的参数是明智的,如果有道理的话。 因此,百分比将接收 16/17 作为文本参数,然后百分比函数可以调用某个辅助函数来查看文本是否是数学文本。 在百分比的情况下,论点并不含糊。 CSS3 声明在此处无效。 因此,其他用户定义的函数可以以相同的方式运行:选择评估有效数学方程的参数。 因此,在这种情况下,严格的数学“强制”使用双括号不一定是正确的。 我认为这会导致对严格数学的想法产生一些阻碍,因为必须在所有情况下它都必须是冗长的。

我们的 --math 选项可能更像是:

  • 总是
  • 分区(默认)
  • 严格的

因此,我们可以弃用 --strict-math=true 并使其成为 --math=strict 的别名

但是,我认为允许函数选择处理这样的参数是明智的,如果有道理的话。

它们已经被允许(只需测试percentage(16 / 17)percentage((16 / 17))--strict-math=on )。
虽然没有一个函数使用:

然后百分比函数可以调用一些辅助函数来查看文本是否是数学。

仅仅是因为这样每个函数都必须有大约 20 行额外的帮助者转换参数arg-checking-smart-arg-handling-stuff,而在大多数情况下,自己的函数代码只是一个(!)行。

每个函数必须多出 20 行? 你怎么算?

如果百分比已经使用单括号严格数学计算,那么我不明白@calvinjuarez的问题。 您的回答似乎暗示单括号无法实现。

每个函数必须多出 20 行? 你怎么算?

这只是一种典型的夸张:也许是 5,也许是 10,也许是 20……如果实际代码/辅助代码比率 -> 0 ,谁会关心确切的数字。 (采取务实的方法,我会在percentage(16 / 17)处停止,只是抛出一个错误,而不是产生NaN% (就像现在),并且不尝试执行任何转换......尽管即使这样它仍然是额外的 4 行代码 - 好吧,我猜可以接受或多或少:)

我最初的回答是暗示他假设这个16/17 -> (16/17)转换是由编译器本身(而不是函数)隐式执行的。


说到选项。 在一个完美的世界中,我梦想根本没有任何选择(即它应该是唯一的,其余的被标记为已弃用并最终被删除)......所有这些额外的选项使代码库非- 可维护.. 即使是一个微小的单行修复/更改边缘情况的数量,您必须预测和测试您需要执行的数量呈指数增长......(几乎无缘无故)。

我只是想它会是这样的:

percentage: function(...) {
  Helper.convertMath(arguments);  // a function that doesn't need it doesn't call it
  // ... the rest
} 

说到选项。 在一个完美的世界里,我梦想着根本没有选择

我同意。 但我们在短期内需要这些选择。 特别是如果我们偏离了严格的数学和遗留行为。 如果我们完善一个“更智能的数学”选项,它们都可以被标记为已弃用。

Helper.convertMath(arguments);

arguments太乐观了。
充其量(不只是计算percentage -无论如何

some: function(a, b, c) { 
    a = convert2number(a, "Error message when fails"); 
    // b is not a number for example
    c = convert2number(c, "Error message when fails"); 
} 

但这真的不是我的观点,我的意思可能是这样的:虽然这总是/曾经是可能的,但没有人愿意编写这样的代码......(有一些有限的例外,)......

是的,我懂你。

percentage(16 / 17)只是抛出一个错误

肯定会有所改善。 (我想不出任何时候NaN%会是有用的输出。)

至于哪些函数会尝试对它们的参数保持智能,没有理由试图预测一切。 @matthew-dean 建议的辅助函数可以相当简单地实现,因为提出和讨论特定功能的功能请求会更智能。

事实上,从一开始,我就说数学函数应该对它们的参数很聪明。

编辑:实际上,只要一个数学函数只传递一个参数。

这是什么状态? 我们收到抱怨LESS 试图将无效的 CSS 属性解析为数学。 例如lost-column: 1/3;中断。

似乎http://www.w3.org/TR/css-grid-1/#grid -template-rowcol 也不适用于 LESS。

有人可以修补这个,所以如果有人明确想要使用 LESS 对他们需要用括号或其他东西包装的属性进行除法吗?

@corysimmons你不是刚刚在#2769 上问这个问题并得到答案吗? o_o

第一次出现时我们没有讨论的一件事。 似乎唯一真正的数学冲突是除法。 划分本质上是一个问题,因为我们本质上是在“重新利用”CSS“分离”字符。

与其尝试以多种方式“包装”除法,或包装所有数学(作为我们对这个问题的第一个解决方案),我想知道为什么我们从来没有谈论过显而易见的事情:_不首先重新利用现有的运算符_,尤其是当它很明显a)使Less代码含糊不清,b)导致冲突。

在我们有时间消化这个之后,将数学括在括号中,即使它只是除法,_仍然_ 会导致数学已经在括号中的情况下的歧义。 (这也可能意味着括号是“数学包装器”的错误选择。)

那么为什么不弃用/作为除法运算符呢? 我知道这是一个常见的除法符号,但是 Less 还做了其他语法权衡来扩展 CSS。 现在我很清楚,我们基本上是在尝试通过使用单斜杠来解决由 Less 首先创建的问题。 我们正在制造歧义,然后试图扭转歧义。

公平地说,其他数学符号在 CSS 的其他部分都被重新利用了,只是它们在数学中的使用不会引起任何歧义。

我本来打算提出一些想法,但是,你瞧,已经有了除法之外的标准替代字符。 除了不在键盘上的÷ ,我发现了这个:

除号在数学上也与比率符号等效,通常用冒号 (:) 表示,读作“是”。 因此,对于任何实数 x 和任何非零实数 y ,该等式成立:

x ÷ y = x : y

换句话说:

lost-column: 1/3;   //  value
lost-column: 1:3;   // division 

我知道在数学中使用冒号需要一些解析器调整,但显然它在数学上是合理的。 我想不出其他符号可以做出更好的替代品。 也许|作为第二选择? 不过会比较随意。

想法?

_或者_,我们仍然可以支持括号和/或方括号内的除法符号,如下所示:

lost-column: 1/3;   //  value
lost-column: 1:3;   // division 
lost-column: (1/3);
lost-column: [1/3];

是的,这就是为什么最初我从./ (受 Matlab vector-div 运算符的启发,它是两个符号,但从视觉上看,它可能是最轻的,因为它是轻量级的点,尽管在 Less 破坏点的上下文中不是一个绝妙的主意)。
: - 这将再次推动雏菊,这个符号在太多的 CSS 上下文中使用。 事实上,已经存在语法冲突:

.foo(<strong i="9">@a</strong>: 1, <strong i="10">@b</strong>: 2) {
  result: <strong i="11">@a</strong> @b;  
}

bar {
    <strong i="12">@b</strong>: 4;
    .foo(<strong i="13">@b</strong>:3); // would mean both @second-parameter:3 and 4/3
}

@seven-phases-max 啊,是的,该死的。 如果只有键盘更大。 是的,用于除法的 2 个字符序列似乎是不可避免的。 我已经很久没有通读整个线程了,所以我忘记了。 ./真的不错。 如果您和@lukeapage都在船上,那将是一个不错的妥协。 也许我们将其移至提案阶段,看看是否有任何反对意见?

回读到这里:

不算它在.之前也需要一个空格,例如16 ./17而不是16./17

不确定我同意。 是的,从技术上讲, 16.是一个有效数字,但有人这样写会很奇怪。 我认为无论你怎么写,空白与否,它都应该用 16 除以 17。

不会有完美的选择,但我认为它比 a) 默认情况下使用/进行除法要好,b) 总是需要括号。 (尽管我过去曾担任过职位,但我也认为是,这有点烦人,尤其是在其他括号内。尤其是因为据我所知,这只是因为除法才需要。是吗?)

我认为无论你怎么写,空白与否,它都应该用 16 除以 17。

确实是的。
虽然考虑得更多,但我希望./会给解析器带来一些额外的技巧(数字解析需要额外的前瞻性才能在./之前停止,而目前它总是以.结尾)。

尤其是因为据我所知,这只是因为分裂才需要。 是的?)

对,就是这样。 不计算calc的代码 - 但对于这一点,我想@lukepage建议的解决方案应该可以

(从技术上讲,如果+, -, *保留在其 CSS颜色操作函数语法中,那么将来可能会有一些额外的歧义 - 但这不应该太戏剧化,因为那里的值具有* 20%形式(因此它们显然可以被检测为一些非较少评估的 expr)。毕竟这些乐趣无论如何都需要一些解析更改,因为当前像(* 20%)会导致解析错误)。

也许……我们一直在做错事。 (绝对包括我在内,因为我最初是“严格数学”功能的狂热支持者。)

我们正在努力使数学普遍适用,但是......它真的不需要。 也就是说,我们试图在显然不应该进行数学运算的情况下进行数学运算。

calc(100% - 10px)示例是最明显的示例。 除非我们投射单位,否则没有可以/应该执行的 Less 计算,我同意 Less 应该停止这样做,默认情况下。 1

让我们看一下用作示例的字体速记属性。

font: italic small-caps normal 13px/150% Arial, Helvetica, sans-serif;
font: italic bold 12px/30px Georgia, serif;

当前的解决方法是将strict-math: on为字体属性。 但是……为什么 Less 应该首先做任何计算? 当然, 13px/150%在数学中是一个有效的语句,但在 Less 中将其视为有效的语句是否合理? 12px/30px您_可以_将其视为有效的数学语句,但是您应该这样做吗? 2

也就是说:在 Less 中,单位的数学运算应该由 _integers_ 和 _floats_ 执行,而不是由单位执行。 我们将这些视为有效的数学语句,就好像人们实际上是这样写数学的。 但我不明白这怎么可能是真的。

也就是说,要求某人将13px/150%13px/1.5是合理的。 即使忽略12px/30px作为数学运算没有意义的事实,我们也不需要知道它不是,我们也不需要将font列入白名单. 如果 Less 作者正在做数学运算,他们会合理地将其写为12px/30 。 这不仅是合理的,而且很有可能_他们一开始是如何写的_。

对我来说,编写 mixin 甚至在单个块中使用类似的东西是司空见惯的:

width: <strong i="5">@size</strong> / 2;
height: <strong i="6">@size</strong> / 2;

我为什么要这样写? _任何人_都这样写吗?

width: <strong i="10">@size</strong> / 2px;
height: <strong i="11">@size</strong> / 2px;

如果@size是一个px单位,则操作 _sort of_ 是有意义的,但是,无论如何,在 LESS/CSS 领域尝试在后一种情况下进行数学运算是没有意义的,因为除数是一个带有单位的值。 第二个看起来不像数学。 它看起来像一个 CSS 值。

如果当乘数或除数是一个带有单位的值时,我们停止对乘法或除法进行数学运算(只需要除法以实现歧义,但乘法也是为了逻辑一致性),我认为这个问题将在很大程度上消失。 相比之下,单位 _are_ 用于加法和减法,但可能不需要(现在是这样)。

<strong i="18">@pad</strong>: 2px;
width: 10px + @pad; 

但是当将一个带有单位的值加/减到另一个带有不同单位的值时,Less 应该不理会它。

<strong i="22">@val1</strong>: 100%;
<strong i="23">@val2</strong>: 10px;
width: calc(<strong i="24">@val1</strong> - @val2);

// output
width: calc(100% - 10px);

要求匹配单位进行加/减(或整数/浮点数),并在数学运算中要求整数/浮点数针对单位(没有单位乘以/除以单位)将解决 99% 的歧义,并且仍然允许有效的数学运算而无需任何新符号.

例如,根据这些规则,背景速记就可以了:

background: no-repeat 10px 10px/80% url("../img/image.png");

%是一个 CSS 单元。 px是一个不同的 CSS 单元。 因此,没有数学。 特殊的例外是零。

background: no-repeat 0 0/80% url("../img/image.png");

如果有人似乎将零除以另一个数字,或者将一个数字除以零,我认为我们可以安全地按原样输出。

边界半径,同样的事情:

border-radius: 30% / 20%;

少会给它一个通行证。 如果有人打算做数学,那么合适的写法是:

border-radius: 30% / 0.2;

好消息是,通过进行这些区分,很明显数学运算 _cannot_ 是 CSS 值,因为,就像border-radius示例一样,有效的 CSS 值需要两边都有单位。 不会有重叠/歧义。

除了我能想到的一种情况,可能还有其他情况:

font: 10px/1.5;

您可以(并且通常应该)将行高表示为一个数字。 (但也可能不应该使用字体速记。)但如果我们将其简化为一种情况,那就太好了。 为font (字体值中的内部函数除外)启用严格数学是一个不错的解决方案。 (我不确定没有更好的方法,但它确实有效。)而且仍然是伤害最低的解决方案,因为这些字体速记值通常出现在导入的 UI 样式库、CSS 重置或自定义字体样式表中。

所以,严格的数学仍然有用,但我认为随着这些变化,不那么重要了,也许将来不需要作为一种选择。

我欢迎画廊的回应/评论。

1 _我意识到我应该说清楚@lukeapage评论和@seven-phases-max 的链接让我朝着这个方向思考,更进一步。_
2 _正如我在查看示例时发现的那样,为字体启用严格数学可能是一个不可避免的解决方案,但我认为其余的逻辑适用。_

仅就某些历史背景而言,重要的是要注意,当 Less.js 首次发布时,铸造单元并没有那么大的问题。 calc()未实现,并且backgroundborder-radius没有斜线作为有效值。 我认为font是唯一让事情出错的地方(具有讽刺意味的是,情况可能仍然如此)。

我唯一关心的是实现方面,例如:对于calc(4px + 2rem + 20%) (实际单位无关紧要),第一个加法结果不是数字结果,因此第二个加法处理程序无法区分它的输入和任何应该抛出错误的not-a-number + 20%语句。 可能不是什么大问题(可以通过放置额外的类型/类型标志来解决),但仍需要进行一些调查。

另一个问题是 ehm,不确定,“redabilty”? 即,对于显式数字,结果看起来非常清晰,对于变量,它开始看起来很模糊,例如: border-radius: 10px <strong i="8">@a</strong> / <strong i="9">@b</strong> 30px; - 在看到@a@b之前,您永远不知道这意味着什么

是的, font仍然是一个问题(可能其他速记属性似乎在双方都使用单位,但我们永远不知道他们接下来会想出什么(也计算#2769 之类的东西)...... A还有一些像font这样的好东西,它会再次开始看起来坏了)。

PS 还有一个问题(可能是一个小问题)。有如下值:

border-radius: 10px / auto;
border-radius: 1px inherit / 2px;
background: ... center / 80% ...;
// etc.

也就是说,要使整个工作正常进行,我们必须禁用任何当前不兼容的 div-operand-errors,以便任何foo/bar1x/barfoo/1x都可以通过 w/oa错误。

我唯一关心的是实现方面,例如:对于 calc(4px + 2rem + 20%) (实际单位无关紧要)

这就是我要说的。 实际单位应该很重要。 无论如何,都应该少管闲事。 4px + 2rem在浏览器中有意义,但在 Less 中没有意义。 没有理由在没有意义时尝试添加它,并导致这些附加问题。

例如: border-radius: 10px <strong i="10">@a</strong> / <strong i="11">@b</strong> 30px ; - 在您看到@a@b定义之前,您永远不知道这是什么意思。

在这种情况下,我们无法从自己身上保存样式作者(与第一个示例相同,如果有人出于某种原因实际上试图向像素添加 rem)。 我相信有各种各样的现有示例,有人可以在其中编写他们的 LESS 代码,以使其难以理解。 这在任何地方都存在。

根据我提出的这些数学规则,请考虑:
calc(4px + 2rem - 2px)

较少可以/将计算为calc(2px + 2rem) ,这实际上非常好,并且实际上是正确的值输出。 现在,Less 将其计算为calc(4px) ,这不是正确或有用的答案。 (是的,如果我们删除单位,目前它是正确的,但单位并非毫无意义,除了少数情况,不可互操作。)Less 将2px + 100%102px ,好像在那个结果,当没有人可能想要这样的结果时。

为了让整个事情正常工作,我们必须禁用任何当前的不兼容 div-operand-errors,以便任何 foo/bar、1x/bar 和 foo/1x 都可以通过 w/oa 错误。

我认为这实际上是最明智的对待它的方式。 像函数一样,如果没有 Less 结果,那么它应该通过。 由于/是多个属性值的有效分隔符,Less 无法知道它_不_有效,除非我们为特定属性添加白名单值。 (不。)在这一点上,结果并不悲惨。 如果传递值在浏览器中无效,则它在视觉上很明显。 如果它有效,尝试将值传递给浏览器似乎更好,而不是抛出错误,因为 Less 不确定。

更少可以/会计算为 calc(2px + 2rem)

恐怕它永远不会,因为这将需要一个全新的优化表达式处理程序,这将是一种矫枉过正(基本上4px + 2rem - 2px(4px + 2rem) - 2px形式存储在树中,以便获得2px + 2rem它必须是一个重新排序引擎来尝试所有有效的改组(在这种特殊情况下微不足道,但对于更多的操作数/运算符来说变得非常复杂)。但没关系,保持4px + 2rem - 2px原样很好(之后所有如果你做4px - 2px + 2rem它是优化的)。

但我这句话的实际意思是类似于:

这样任何 foo/bar、1x/bar 和 foo/1x 都可以通过 w/oa 错误。

即 expr.evaluator 的(4px + 2rem) - 2px将类似于foo + 2px ,因此工作它也不应该为那种事情产生错误。
实际上,我测试了foo/bar, 1x/bar, foo/1x并且它们已经通过了无错误(奇怪的是我认为它们确实抛出了),但是其他运算符会导致各种奇怪的事情(虽然没有什么真正重要的,只是解决每个案例的问题逐个)。

恐怕它永远不会,因为这将需要一个全新的优化表达式处理程序,这将是一种矫枉过正(基本上 4px + 2rem - 2px 在树中存储为 (4px + 2rem) - 2px 所以要获得 2px + 2rem 它有成为重新排序引擎以尝试所有有效的改组(在这种特殊情况下微不足道,但对于更多的操作数/运算符来说变得非常复杂)。

为什么要洗牌? 您可以在相同的优先级(因此树为Sum(4px, 2rem, -2px) )扁平化运算符,收集具有兼容单位的术语(可能通过预先规范化单位),并简化每个部分。 它是符号代数,其中单位被视为自变量。

我想自己编写它,但是有很多库可能经过更好的测试并且更可能是完整的。 我敢打赌一些用 Javascript 编写的开源优化编译器有这样的简化子系统。

重点是,虽然这不是一个容易解决的问题,但更一般的问题已经很好地解决了,这样的子系统可以在其他方面对 Less.js 有用。

您在相同的优先级上展平运算符(所以树是 Sum(4px, 2rem, -2px)),

究竟是什么让代码认为某些表达式树实际上是可展平的? (所以我的“suffling”不是关于一些特定的推导算法,而是“尝试所有这些”的捷径,包括你的“扁平化”)。

但是有很多库可能经过了更好的测试并且更可能是完整的。

我不确定你是不是认真的。 因此,您认为将 Less 树转换为外部 lib 树并返回的所有代码(不算那些 JS 库中没有一个可以处理 CSS 单元)实际上值得优化特定的4px + 2rem - 2p案例吗? 唔...

所以,完全没问题(我并不是说这是不可能的,只是它永远不值得) - 欢迎尝试和公关。
(另外,为了防止子表达式优化甚至不是这张票的目标,甚至前三名都不是,这可能很重要)。

究竟是什么让代码认为某些表达式树实际上是可展平的? (所以我的“suffling”不是关于一些特定的推导算法,而是“尝试所有这些”的捷径,包括你的“扁平化”)。

解析器确定上下文是否是例如“长度”,以及子树是否可以解释为“长度”。

我不确定你是不是认真的。 所以你认为所有将 Less 树转换为外部 lib 树并返回的代码

它需要被解析成一个语法树。 从那里,输出代表代数表达式的字符串将相对简单。 返回可能更难:它可能需要从字符串中再次解析,或者是的,它可能需要采用外部库的树。 难度取决于选择了哪个库。

(不算那些 JS 库中没有一个可以处理 CSS 单元)

您只需将单位转换为代数变量。 当表达式为符号形式时,甚至可以进行替换(例如mm -> px )。

实际上值得优化特定的 4px + 2rem - 2p 案例吗?

我正在为表达式优化提出一个替代建议,它不那么困难(作为 Less 自己的代码必须解决的算法问题),而且比你所说的更有用。

代数化简可以解决带括号的子表达式的问题,并允许 Less 添加更多数学特征。

欢迎尝试和公关。

我会尝试。 我今天才开始研究 Less,我在完成项目时遇到了问题,所以我承认我可能不会得到 PR。

也以防万一可能重要的是要注意,子表达式优化甚至不是这张票的目标,甚至不是前三名

我知道。 我来这里的原因之一。 为什么这么咬?

为什么这么咬?

好吧,也许......如果是这样 - 我很抱歉(看起来我对某人准备致力于解决几乎不存在的calc(4px + 2rem - 2px)问题的努力和时间感到震惊。可能我们只是有非常不同的概念轻量化)。

并允许 Less 添加更多数学特性。

你能列举几个吗?

解决几乎不存在的calc(4px + 2rem - 2px)问题

嗯? 少一点都应付不过来。 [因为我误解了正在解决的问题,所以被删除了]

为了简化/重申提案- 数学变化如下

  1. 加法和减法只会在相同的单位上计算。 例如1px + 2px = 3px , 1px + 1vh = 1px + 1vh
  2. 除法和乘法只能用无单位的除数/乘数计算。 例如10px/2 = 5px , 10px/5px = 10px/5px
  3. 没有单位的价值比率将类似于#2。例如1/3 = 1/3
  4. 为简化起见,可以将带有部分无效子表达式的表达式视为无效的数学表达式并按原样输出。 例如1px + 2vh / 2 = 1px + 2vh / 2

该提案解决了以下问题(来自该线程):

  • font: 10px/5px和类似(ratio)语法(无计算)
  • calc(100vh - 30px) (不计算)
  • lost-column: 1/3和类似的自定义比率语法(无计算)

同时,这些更改将保留 99% 的典型 Less 数学用法。 同样,现有的unit()convert()函数允许用户将值转换为兼容的数学单位。

少一点都应付不过来。

您只是没有阅读我和@leewz在上面所说的内容。 它与calc(100vh - 30px)无关。 而我的“解决几乎不存在的问题”仅用于“优化calc算术表达式”。

@seven-phases-max 哦对了。 对不起。 不,我们不需要优化。 只要弄清楚什么时候数学。

此问题已自动标记为陈旧,因为它最近没有活动。 如果没有进一步的活动发生,它将被关闭。 感谢你的贡献。

删除 slate 标签,因为问题仍然很重要,而且随着 CSS 的发展只会变得更糟。

@马修院长
在这里玩一会儿代言人......

12px/30px您_可以_将其视为有效的数学语句,但是您应该这样做吗?

是的; 你应该。 它计算一个标量值,表示两种尺寸之间的比率,这在转换为 em 单位时非常有用。

假设我有一个已知的基本字体大小为 16px 和一个已知的标题大小为 24px,两者都隐藏在变量中,然后我想用正确的字体大小分配一个特定的标题风格,但在一个 em 单位中。

@fontsize-body    : 16px;
@fontsize-heading : 24px;

// ( ... and then somewhere else ... )

.heading {
  font-size : unit(@fontsize-body/@fontsize-heading, em);

  // Or if dividing compatible unit values is produces a unit-less scalar
  // value ( as it really _should_ -- mind you... ),  you could prefer:
  font-size : @fontsize-body/@fontsize-heading * 1em;
}

如果您需要支持将兼容单位的划分作为数学表达式,那么您将继续需要支持一种方法来消除文字 CSS 与 Less 数学表达式的歧义,以涵盖每一半情况。

现在授予,这可能涉及使用括号来强制数学表达式并默认采用 CSS 文字。 但这似乎是错误的并且容易出错。 它需要很多预先准备好的特殊情况,例如border-radiusfont速记,并要求 Less 不断更新这些情况。 (正如一些新的网格属性所说明的那样,除法符号也出现了同样的问题。)

所以...

为什么不翻转你的推理呢? 如果某些东西看起来像数学表达式并且它具有兼容的单位,那么默认情况下它将被视为数学表达式。 如果你不想发生这种情况......好吧; 然后使用~"..."逃生舱口。 毕竟,这正是它的用途......

我目前对该提案的看法:

  • 停止将/视为任何地方的除法
    因此只有1anything./3whatever和(可选) (1anything/3whatever)被 Less 计算。
  • +-*保持不变
  • calc子问题通过不评估任何算法来解决。 calc(...)表达式(不过,再一次,冗余括号也可能有它们的效果)。

@七阶段最大

问题在于/作为除法运算符非常根深蒂固。 使用任何其他符号对用户来说都是一个艰难的卖点。 您正在使用一般用例并将其用于几乎没有人使用过的特殊用例(CSS 速记中的/ )。

@rjgotten

与此有关的问题是 / 作为除法运算符非常根深蒂固。

不在 CSS 中。

对于几乎没有人使用过的特殊用例(CSS 简写中的 /)。

到目前为止, /已经被大量使用,相比之下,如今的 Less div 操作完全比 CSS /出色得多(不像几年前,CSS /大多只能在font内找到)。

@seven-phases-max 感谢您一直关注它。 我添加了 Stale bot 来帮助我们管理问题,并提供了相当多的时间来标记过时。 我还免除了两个标签,“bug”和“up-for-grabs”。 欢迎对此提出任何建议,例如将其他标签列入白名单。 文件在这里: https :

回到问题线程......

@rjgotten
您的用例会产生任意问题。 论据是它是有用的。 但是以这种方式构建变量会产生一个问题,该问题可以通过语法避免,正如@seven-phases-max 指出的那样,模棱两可。

即使从表面上看,以 CSS 作为 Less 原则的指南,在计算中,您也不能将 12 像素除以 30 像素。 在 Less 中这样做不仅会产生歧义问题,而且会无缘无故地脱离模型(除了历史原因)。 可能 Less 缺少的一件事只是一种提取单位值的数值的方法,这样 Less 就不必为除法做这种数学魔法。

所以,简单的答案是你的例子看起来像:

font-size : @fontsize-body/number(@fontsize-heading) * 1em

但我也同意@seven-phases-max 的提议。 我们仍然可以在calc()计算 _vars_,但不能计算数学。 并且不评估除括号之外的除法。 我认为这是一个很好的妥协。 而且,可能,如果您想保留将一个单位除以一个单位但保留该单位的魔法除法数学(这仍然很奇怪,但这很好),它可能会发生在括号内。

我知道 Less 中的数学主题有一些不同的偏好,但我认为如果我们能够就引起最少副作用并且最容易推理而不需要大量维护的事情达成共识,那就太好了或发展负担。

我认为我们都在同一页面上,Less 中当前的(默认)数学方法被打破了。 我们收到的反馈是,将所有内容作为默认设置更容易推理,但很麻烦。 所以我希望有一些好的中间立场,我们可以很快将其作为默认设置(可能在 4.0 中?)

可能 Less 中缺少的一件事只是一种提取单位值的数值的方法

如果您不指定第二个参数, unit函数实际上会这样做。 但这更多是标量当前使用没有定义单位的Dimension节点类型实现的事实的副作用。

的确; 它有很长的路要走,但如果你_真的_想避免划分具有兼容单位的维度,那么撕下单位会起作用。

我还要补充一点,我强烈反对在这种特定情况下任何“兼容单位”的猜测(例如让a/b仍然是一个部门,而b/c不是)。
仅仅是因为:

  • 异常处理是万恶之源(例如#3047 - 见下文,http://stackoverflow.com/questions/19705791- 我记得我找不到 SO 问题的原因,直到我真正跨过无数行调试器中涉及的 Less 代码)。
  • 最重要的是,它不是面向未来的,即如果重大的重大变化不可避免,我们最好确保一次(最好是永远)......而不是像他们添加一些涉及a/b新 CSS 功能

所以对我来说,“兼容单位”的东西更像是完全不相关和正交的东西(可能会有一些关于有或没有-su结果单位的讨论,但那是另一回事了)。


(无关:)
顺便说一句,谈到上面的例子:
@rjgotten如果你有:

@fontsize-body/@fontsize-heading * 1em; 

在你的代码中的某个地方,两个变量中的一个是px你实际上使用了一个错误:)
正确的代码是:

1em * @fontsize-body/@fontsize-heading;

总是导致每个http://lesscss.org/features/#features -overview-feature-operations 的定义明确的单元(计算 #3047 被修复,该错误再次是由太多代码库中围绕“兼容单元”的猜测代码)。 不需要--sunumberunit bla-bla ... 当前-su行为,例如“如果您看到不兼容的单位就抛出错误” ,即一个简单的验证,是很好的(对我来说)。 我看不出有任何需要1px/2px->.51px*2px->2px^2曼波-詹博过度设计。 但这又是另一个不相关的故事)。

@七阶段最大

实际上使用了一个错误

嗯……是的; 你是对的,当然。 幸运的是,我实际上在任何地方都没有在生产中使用该代码。 这只是一个简单的例子来说明这一点。

我还要补充一点,在这种特殊情况下,我强烈反对任何“兼容单位”的猜测(例如让 a/b 保持为除法而 b/c 不为除法)。

我想我更愿意将其作为对那些想要裸除数的人的橄榄枝。 但我认为您的评论 [此处] 是最可行的建议。 “严格数学”的初衷是消除歧义。 我认为关注点变成了 mixin 和函数调用中的操作,导致了括号内的各种括号。 但是,总的来说,我和你一样,为了使 Less 中的数学变得容易,具有讽刺意味的是,由于模糊性的增加,它也变得非常困难。

此外,我后来意识到font: 10px/3是有效的速记。 所以真的没有算法解决方案可以帮助那里。

回到你的问题,@rjgotten ...

为什么不翻转你的推理呢? 如果某些东西看起来像数学表达式并且它具有兼容的单位,那么默认情况下它将被视为数学表达式。 如果你不想发生这种情况......好吧; 然后使用 ~"..." 逃生舱口。 毕竟,这正是它的用途......

Less 与 CSS 的想法/关系类似于 TypeScript 与 JavaScript。 也就是说,将您的有效.css重命名为.less ,您就可以开始添加 Less 功能了。 类似于如何将.js重命名.ts并开始添加 TypeScript 功能。 如果您不添加任何内容,您应该得到相同有效的 Less / JavaScript 输出,因为这些语言是基本语言的超集。

然而,在 CSS 中的这些比率或其他/除数的情况下,默认情况下,Less 已经失败了。 你的常规 CSS 随意变成了一个具有不同结果的 Less 数学表达式,即使你没有做任何改变。 这违反了语言的约定。 能够将您的.less更改为一个完全不同的 Less 表达式以恢复您开始使用的原始 CSS 没有抓住重点。 永远不需要这项工作。 Less 不应该要求您将有效的 CSS 更改为兼容的 Less 表达式,以便恢复您最初拥有的有效 CSS。 那只是一个破碎的模型。

同样的推理适用于calc() 。 是的,您可以对表达式进行字符串转义,但您不必这样做。 .css重命名为.less应该产生相同的有效 CSS。 这应该是项目的基本目标,不干扰/覆盖/过度解释原始样式表。 除了首先使用解析器/语言之外,其他任何事情都试图将问题推给开发人员。

是的,您可以对表达式进行字符串转义,但您不必这样做。 .css 重命名为 .less 应该产生相同的有效 CSS。 这应该是项目的基本目标,不干扰/覆盖/过度解释原始样式表。 除了首先使用解析器/语言之外,其他任何事情都试图将问题推给开发人员。

那。

LESS 知道哪里允许/以及它不在 css 中的位置。 在它不是但无论如何出现的地方,它应该假设要完成数学运算。 此外,如果数学被圆括号包围,css 中不允许使用圆括号,则应由 LESS 解释。

换句话说,LESS 应该尝试解释尽可能少的数学以获得有效的 css。 一旦输出有效,停止执行任何更多的数学运算。

@thany

太多关于编译器知道的假设(其中一些完全是错误的)。
无论哪种方式,“圆括号”模式几乎都是--sm=on所做的,所以使用它并忘记这个线程(很可能你只是没有在你的项目中使用任何数学在calc旁边(介绍了一些在 Less 设计多年之后)所以你看不到额外的括号是多么令人讨厌。但其他人确实如此。)


其余见https://github.com/less/less.js/issues/1880#issuecomment -345194431。

@seven-phases-max 不要忘记/backgroundborder-radius速记中也有含义,可能还有其他我现在没有想到的。 LESS 会很高兴地将它们视为一个部门。 不管有没有严格的数学模式,LESS 都应该“知道什么时候停止”做自己的小数学。

@thany
LESS 应该“知道什么时候停止”做自己的小数学。

不,不应该。 没有办法知道未来带有除法斜线的 CSS 速记会出现在哪里。 让 Less 编译器“知道”这是一种根本上有缺陷的方法,而本次讨论正是试图找到解决方案。

到目前为止, /作为除法运算符有两种合理且可预测的选择:

  • 始终如此对待它,并要求显式转义以用于其他用途。
    这将打破 Less 语法是 CSS 语法的严格超集的行为。
  • 永远不要将其视为除法运算符,除非 __ 在已知的数学上下文中。
    在当前的--strict-math=on行为中可以/将决定已知的数学上下文。

(另外;请注意,Less 名称不再全部大写。)

不要忘记 / 在 background 和 border-radius 速记中也有含义,

这基本上是这个线程的开始。
并在https://github.com/less/less.js/issues/1880#issuecomment -345194431(没有关于编译器应该或不应该知道什么的任何假设)上查看拟议更改的摘要。

不,不应该。 没有办法知道未来带有除法斜线的 CSS 速记会出现在哪里。 让 Less 编译器“知道”这是一种根本上有缺陷的方法,而本次讨论正是试图找到解决方案。

我完全同意这一点。 @thany虽然您在引用我所写的内容时同意我的

@rjgotten

切勿将其视为除法运算符,除非它在已知的数学上下文中。
在当前的 --strict-math=on 行为中可以/将决定已知的数学上下文。

为了澄清,这部分(我同意):

切勿将其视为除法运算符,除非它在已知的数学上下文中。

实际上有 4 种可能的解决方案,我知道您知道,但只是重新总结该线程:

  1. 仅在括号中进行所有数学运算。 这显然被公地拒绝了,这很好,尽管它仍然可以作为可选的切换( strictMath )使用。
  2. 处处进行所有数学运算,但仅在括号中进行除法。
  3. 处处进行所有数学运算,但仅在括号中进行除法。 除非除法运算符打印为./
  4. 在任何地方做所有数学运算,但修正数学运算,使12px/4px不会导致除法。 (乘法和除法仅适用于无单位值。)换句话说,除法无处不在,但规则更加保守。 在它不能解决问题的情况下,求助于逃避。 因此,这不是一个完整的解决方案,但仍然是对当前情况的(有争议的)改进。

从可用性的角度来看,我喜欢让数学变得“更聪明”,就像#4 。 从工程和维护的角度来看,为了防止未来的 CSS 更改,我喜欢#3作为最强大的解决方案。

但是,我认为实际上,我们需要同时执行#3#4才能修复calc() 。 现在,在进行数学运算时,Less 忽略所有单位真是一团糟。 100vh - 12px永远不应该被 Less(括号与否)触及。 但是 IMO 也不应该12px/4px (括号与否),但我可能是那个的少数。

所以,我认为这与其说是“数学与 CSS 语法冲突”的问题,不如说是 Less 过早地开始解决数学方程的方式过于激进。

乘法和除法仅适用于无单位值。

它不会成功,因为有以下情况:

font: small-caps bold 24px/3 ...;
lost-column: 1/3;
// etc.

它们不是 div。

但是,我认为实际上,我们需要同时执行#3#4才能修复calc()

calc()是一种痛苦。 具有讽刺意味的是,它_可能_最好通过将其实现为实际的 Less 函数来解决,理想情况下,这将采用其解析的表达式树并尝试简化表达式。 也就是说:它应该预先计算并组合兼容的组件,例如4px + 12px (或4px + @a当已知@a具有像素值时)但留下不兼容的组件,例如那些与不兼容的单位,单独。

例如

<strong i="17">@a</strong> : 4px;
<strong i="18">@b</strong> : 2;
width : calc(100%/<strong i="19">@b</strong> - 10px + @a);

最终应该呈现

width : calc(50% - 6px);

(从 https://github.com/less/less.js/issues/1880#issuecomment-345345735 重复我自己)
而且我认为为了优化calc的表达式而对编译器进行大量过度设计没有任何好处。 如果您正在编写calc那么您可以使用浏览器来完成工作,无论您在那里有什么长表达式。 因此,正如上面已经提到的,我是为了“不要触摸calc内的任何东西”(= 不要试图变得比真正需要的更聪明)并将其留给浏览器(用于 css-minifier,因为,如果我没记错的话,其中一些已经在优化 calc 子表达式方面做得很好)。


“智能单元行为 mamabo-jambo”让我想起了min/max怪物(不可维护且从未使用过的代码的膨胀堆栈)-我多么后悔当时没有对“units mambo”大喊大叫,哦(所以我会一直在这里抱怨直到“取决于操作数单元的不同操作符语义”的想法完全消失:P)。


PS 一旦calc成为接收非算术计算表达式的函数(无论如何它都必须这样做),您就可以编写插件并使用所需的任何优化来覆盖它。

@rjgotten
让 Less 编译器“知道”这是一种根本上有缺陷的方法

我认为这是一个从根本上正确的方法。 LESS 是 CSS 的编译器,因此 LESS 知道它正在编译成什么,这在世界上是很有意义的。

@马修院长
少不应该也不知道什么时候“停止做数学”。 我要说的是,突破性的变化应该是,Less 一开始就开始数学(使用美国/加拿大主义)更加保守。

有趣的是,你从另一边想起来,可以这么说。 这是我的建议:

background: url(...) no-repeat 50% 50% / 40px + 10px 40px;

LESS 应该在这里做什么,对我来说很明显:

background: url(...) no-repeat 50% 50% / (40px + 10px) 40px;

导致:

background: url(...) no-repeat 50% 50% / 50px 40px;

它不应该计算50% / 50px部分,因为(1)它不应该因为不兼容的单位和(2)因为这对于background值已经足够了. 所以这就是它“停止做数学”的地方。

这就是我所说的“不知道什么时候停止”的意思。

是不是这样的不同属性:

padding-left: 50% / 10px + 5px;

它应该因错误(不兼容的单位)而中断。 一种可能的输出是50% / 15px ,这对该属性无效。 另一个结果可能是5%它目前会这样做,这在各个方向都是错误的。
和:

padding-left: 50px / 10px + 5px;

应该导致:

padding-left: 10px;

正如预期的那样。 因此,在这种情况下, /是无效的padding-left ,并且考虑到LESS和做它的数学啄。

@马修院长
实际上有 4 种可能的解决方案,我知道您知道,但只是重新总结该线程:

多一个:
5) 将\运算符用于 LESS 中的除法,并弃用/ 。 MATLAB 有类似的东西,某些 BASIC 风格用它来强制整数除法。 所以使用反斜杠并非完全闻所未闻。

/编辑
我们还可以游说在键盘上包含÷键并将其用作除法运算符。 这是我在小学学到的:)

你的建议之前已经讨论过很多次了(不要犹豫,看看这里引用的线程)。 所以这里只是一些懒惰的评论:

\运算符用于 LESS 中的除法,并弃用/

https://github.com/less/less.js/issues/1872#issuecomment -35245890

足以background ... 对padding-left无效

遇到“伙计们,我的浏览器/polyfill/任何刚刚添加/更新/扩展了对fnord属性的支持,你能帮我发布一个新的 Less 版本吗?” 问题。
遇到font问题
等等等等
好吧, @rjgotten已经在上面评论过为什么这种“知识”是无处可去的。

@七阶段最大
反斜杠只是一个建议。 您不妨使用?进行除法。 这并不重要。 我想,我的建议是不要使用一个具有非常不同和含糊不清的含义的字符( / )。

遇到“伙计们,我的浏览器/polyfill/任何刚刚添加/更新/扩展了对fnord属性的支持,你愿意为我发布一个新的 Less 版本吗?” 问题。

CSS 是一个定义明确的标准。 你不应该支持标准之外的任何东西。 那是你的问题,我觉得。 您不能支持fnord属性,因为它不是任何标准的一部分。 当这个新的未指定属性发生时,LESS 可能会回退到它的默认行为,这可能是当前的,或者需要括号,或者其他任何东西,只要它没有歧义。

遇到字体问题。

字体问题证明/问题从 LESS 的绝对开始就存在。 不仅仅是当background能够包含背景大小的值或border-radius出现时。 Tbh,通过说明字体问题,您刚刚对自己提出了最好的论据:)

Tbh,通过说明字体问题,您刚刚对自己提出了最好的论据:)

我想你误解了一些东西。 最初是提议完全删除/作为 div 运算符。 所以对于其余的东西,我想这与你没有注意你回复的内容是一样的。

CSS 是一个定义明确的标准。

如果您打算坚持在 TR 级别已经完全成熟的规范部分,也许吧。
否则? 不,这不对。 有新 CSS '模块' 的卫星规范和现有模块的修订版,如果不是每周的话,每个月都会出现新的添加内容。

@七阶段最大

它不会成功,因为有以下内容: font: small-caps bold 24px/3 ...

不,我明白了。 我的观点正是这样:无单位只有 div/multiplication 可以减轻问题,但不能解决问题。

而且我认为总的来说,您对所有部门的./建议仍然很合乎逻辑。

@thany而不是回应所有具体的例子,我会说一般来说,让较少的数学变得更聪明的努力只会把球踢到不同的码线。 它仍然是相同的问题,只是在不同的地方。 正如@seven-phases-max 所说,您建议的任何内容都没有得到讨论。

而且我认为为了优化 calc 中的表达式而过度设计编译器没有任何好处。 如果您正在编写 calc 那么您可以使用浏览器来完成工作,无论您在那里有什么长表达式。 因此,正如上面已经提到的,我支持“不要触摸 calc 中的任何内容”(= 不要试图变得比真正需要的更聪明)并将其留给浏览器(或用于 css-minifier,因为如果我没记错的话) ,其中一些已经在优化 calc 子表达式方面做得很好)。

我完全同意这一点。 如果我们只是将calc()列入白名单,我们将消除 99% 的新数学相关问题。 虽然我已经提出了一些方法,Less 可以更聪明地进行数学运算,以避免calc()问题(这也许应该),如果这被解释为反对这个想法的论据,我深表歉意。 我也支持这个。

唯一的警告(如此处/其他地方所述)是开发人员将不可避免地希望在calc()使用变量,因此我们需要小心确保我们继续交换变量,但不要这样做数学。 我不确定这有多具有挑战性。 如果我们能够做到这一点,我会支持今天对calc()处理方式进行更改。

@thany

字体问题证明 / 问题从 LESS 的绝对开始就存在。

这可能是正确的并且是一个公平的观点,但是有许多合适的解决方法,并且在当时使用font属性速记不一定是标准做法。 确实是因为多重背景和calc()在 Less 开始后才出现,这使得这更成为一个问题,现在 CSS Grid 语法意味着现在存在大量冲突,最初在日常实践中不存在冲突。

顺便说一下,这就是 Sass 解决问题的方式,如下例所示:

p {
  font: 10px/8px;             // Plain CSS, no division
  $width: 1000px;
  width: $width/2;            // Uses a variable, does division
  width: round(1.5)/2;        // Uses a function, does division
  height: (500px/2);          // Uses parentheses, does division
  margin-left: 5px + 8px/2px; // Uses +, does division
  font: (italic bold 10px/8px); // In a list, parentheses don't count
}

这不是一对一的,因为您可以(当前)在 Less 函数的参数中进行数学运算,并且 Less 函数可以返回像素值(所以 Less 可以执行font: print10px()/8px ,理论上?不是吗?),所以我我只是为了说明性地粘贴它,而不是作为任何建议。 他们是如何解决这个问题的,这很有趣。

就我个人而言,我认为让开发人员尝试记住在哪些情况下会根据魔术表达式的存在进行数学运算有点疯狂(比如在前面加上+ ?),但对于每个人来说.

就我个人而言,我认为让开发人员尝试记住在哪些情况下会根据魔术表达式的存在进行数学计算是一种疯狂的制作

+1


除了lessc --sm已经解决的问题之外,甚至还不算“解决方案”解决了这里讨论的任何问题。 1/2$var/2不同结果只是一个惊人的精彩...... ~愚蠢~ “调试愉快,失败者!”

@马修院长
顺便说一下,这就是 Sass 解决问题的方式,如下例所示:

这是一个绝妙的解决方案,无需求助于其他运营商。
如果表达式可能是有效的 CSS,请保留它。

就我个人而言,我认为让开发人员尝试记住在哪些情况下会根据魔术表达式的存在进行数学计算是一种疯狂的制作

不同意。 这是一组简单的规则,与您需要记住的任何其他(疯狂与否)规则没有什么不同。

有一些边缘情况,数学确实发生而没有意义,但是您只需应用括号即可完成。

甚至不认为“解决方案”解决了这里讨论的任何问题,而不是 lessc --sm 已经解决的问题。 当我想要的只是一个除法时,为什么我会写 0 + 1/2 而不是 (1/2) ? 1/2 和 $var/2 的不同结果只是一个非常出色的......愚蠢的“调试愉快,失败者!” 信息。

哈,是的,这个。

@thany

这是一个绝妙的解决方案,无需求助于其他运营商。
如果表达式可能是有效的 CSS,请保留它。

不要陷入杂草,但出于语法原因和语言一致性,它不会对 Less 起作用。 这对 Sass 来说可能很棒,我会说这是有争议的,但从设计的角度来看,我并没有亲自参与该项目,所以谁说。 我所知道的是,桌面上的选项是最好的起点,我相信如果您花尽可能多的时间浏览与此问题相关的一些消息线程并花时间研究语言,那么您会来的得出同样的结论。

我们无法摆脱的一个观察结果:如果您导入有效的 vanilla CSS,其输出在功能上应该是相同的。 所以我能得出的唯一结论是 LESS 不应该触及已经可能是有效 CSS 的表达式。 如何做到这一点,不取决于我。 但事实仍然是,导入 vanilla CSS 是不可靠的,主要是因为 LESS 过于急切地执行部门。

在 Sass 中导入 vanilla CSS 几乎完美无缺,因为如上所述,如果/操作符没有指示编译器根据一些简单的语法规则执行操作,Sass 会单独保留它。 这些语法规则描述了在有效的 vanilla CSS 中不能出现的强制除法的方法,这就是为什么它很出色。

你仍然在用你自己的想象而不是他们告诉你的东西来争论。 回答一个简单的问题:“ 0 + 1/2怎么可能比(1/2)更好?”。 如果 100%-CSS 兼容性是你唯一关心的设置可爱的-sm并忘记这个线程。

我们无法摆脱的一个观察结果:如果您导入有效的 vanilla CSS,其输出在功能上应该是相同的。 所以我能得出的唯一结论是 LESS 不应该触及已经可能是有效 CSS 的表达式。 如何做到这一点,不取决于我。 但事实仍然是,导入 vanilla CSS 是不可靠的,主要是因为 LESS 过于急切地执行部门。

这部分我基本上同意,我认为你会在这个线程中找到很多关于这一点的同意。 大多数分歧都围绕解决方案展开,每个解决方案都有不同的副作用。

我会优先考虑进行这些重大更改:

  1. 括号外的数学需要./而不是裸/ 12px./10px看起来还是有点奇怪。

@seven-phases-max - 我想重新审视反斜杠。 与此相关,我知道你提到了https://github.com/less/less.js/issues/1872#issuecomment -35245890,但我没有看到任何彻底的冲突,因为这些标识符不是,我认为不可能数学表达式的一部分。 还是我错了? 我想有可能想出一个理论案例,比如函数名称,其中包含一个转义字符作为名称的一部分,但这似乎更像是一种智力练习,而不是现实世界的案例。 转义选择器,是的,它们通常出于各种原因使用,但在属性值中,似乎不太可能,或者在极端情况下,可以使用历史(只是转义此文本)解决方法来中断/解决方法。

我们能否进一步探讨一下,使用单个反斜杠进行除法会导致现实世界的冲突吗? 我的直觉是\/周围的当前情况问题少,而且比./开发人员更友好。 如果我们进行了研究并发现它是可行的,那么我们可以进行重大更改以在任何地方使用它,而不是上下文切换允许在括号中使用/ 。 然后我们可以使用旧式交换机支持/

  1. (第二优先级) calc()是特殊情况,以便它可以进行变量替换但不会计算任何数学表达式

我们能否进一步探讨一下,使用单个反斜杠进行除法会导致现实世界的冲突吗?

好吧,问题是\anycharacter是有效的 CSS 并且有它自己的含义。 当然,您在实际项目中几乎找不到这样的代码(可能除了 ie \9类似的 hacks),但是……我们想养活那头狮子吗? 通过引入另一个相同的“呃呃”来修复一个“呃呃,我的 100% 有效的 CSS 无法编译”听起来有点奇怪:)

至于calc我想我们从一开始就达成了共识——所以基本上只需要等待志愿者来实现它(我估计只需 5-6 行新代码即可完成快速修复——所以这真的只是一个勇敢的人去做这件事 - 次要的实施细节可能会有所不同,但我认为他们可以在过程中决定)。

嗯,问题是 \anycharacter 是有效的 CSS 并且有它自己的含义。 当然,您在实际项目中几乎找不到这样的代码(可能除了 ie \9-like hacks),但是……我们想养活那头狮子吗? 通过引入另一个相同的“呃呃”来修复一个“呃呃,我的 100% 有效的 CSS 无法编译”听起来有点奇怪:)

我听到你说,这是一个可能的权衡。 是的,我知道\anycharacter是有效的 CSS。 我想我想知道这是否是一组更好的权衡。 只是当我写出12px./10px它在语法上感觉很奇怪。 我觉得 Less 在语法上已经尝试在不产生冲突的情况下尽可能多地重新利用 CSS。

就像, ./提供了语法清晰性并完全避免了冲突,但是在数学中到处强制执行括号也是如此,这就是我支持它的原因,但是有强烈反对,我在这里很担心。 那么是否有任何合法的案例我们会将10px\10误认为是开发人员想要逃避\10的意图? 我知道这是一个很难的理论,你的观点可能是我们真的不知道......这是一个复杂的问题,添加新语法总是令人担忧,尤其是使用 Less,因为我们并不了解所有 CSS狂野或未来的 CSS。

至于 calc,我想我们从一开始就达成了共识——所以它基本上只是等待志愿者来实现它(我估计只需 5-6 行新代码即可完成快速修复——所以它实际上只是一个勇敢的人这样做 - 次要的实现细节可能会有所不同,但我认为它们可以在过程中决定)。

好的! 我们应该单独跟踪它以提高能见度吗?

@seven-phases-max:

当然,您在实际项目中几乎找不到这样的代码(可能除了 ie \9 -like hacks)

。 哦,那个傲慢的“西方人”...... :)

@七阶段最大
回答这个简单的问题:“0 + 1/2 怎么可能比 (1/2) 更好?”

我不明白你要去哪里。 (1/2)应该由 LESS 执行,因为它不可能是有效的 CSS,所以它必须是 LESS。 0 + 1/2应该变成1/2 ,其中 LESS 执行0 + 1部分,因为那部分不能是有效的 CSS。 1/2部分可能是有效的,所以最好不要碰它。

@thany
好的,现在意识到(1/2)在 Less 和 Sass 中都如您所愿。
0 + 1/2 (以及1 * 1/2等)是您在上面称为“辉煌”的解决方案的一部分,“出色的解决方案”结果是0.5
仍然不知道这里发生了什么?
再次重读上面的所有内容(从您的第一篇文章开始)并尝试回答自己“我到底在抱怨什么?”。

@七阶段最大
并且 0 + 1/2(以及 1 * 1/2 等)是您在上面称为辉煌的解决方案的一部分,而“卓越的解决方案”结果是 0.5。

不,解决方案是1/2而不是0.5 ,因为1/2可能是有效的 CSS。 您似乎不希望 LESS 知道斜线何时有效,因此假设它总是可能有效。 因此1/2是唯一合乎逻辑的结果。 同样, 2 * 1/2将导致2/2 ,因为*否则会使 CSS 无效。

仍然不知道这里发生了什么?

我很清楚这里发生了什么。 LESS 正在热切地执行数学除法,而盲目地忽略了单位。

再次重读上面的所有内容(从您的第一篇文章开始)并尝试回答自己“我到底在抱怨什么?”。

没有必要进行人身攻击。

LESS 正在热切地执行数学除法,而盲目地忽略了单位。

所以就是你要抱怨的,对吧?

没有必要进行人身攻击。

那我应该怎么做呢? 一次又一次地(又一次)重复原来的两个帖子? 直到你清楚:
@社区

使用-sm选项

@thany

那么它应该默认打开。

@seven-phases-max:

不可能是因为这会立即破坏那里的无数项目。 因此,如果您将默认行为视为问题,只需设置记录的选项即可。


所以你在重复“它应该”、“它应该”、“它应该”期待什么? 猜猜我们更容易回答“不,它不应该”,而不是浪费我们的时间试图详细解释为什么您的建议不起作用或一般没有意义(您不想解释的解释)理解或根本不能)。


那么这个线程是关于什么的? 它是关于“意识到虽然最终破坏性的改变使“ -sm行为默认是不可避免的,但我们必须为更舒适的算术提供设施,而不是可怕的: margin: (1/2) (3/4) (5/6) (7/8);为那些谁经常使用该算法”。
你在这里发帖要么建议一些不比(或完全相同)已经存在的-sm行为更好的东西,要么与从一开始就没有问题的东西争论(比如那里)。 换句话说,只是一个随机噪音

@seven-phases-max @thany让我们将温度降低一个档次。 各地都有强烈的意见。

我认为大多数人都在同一页面上,理想情况下不会被 Less 解释为数学表达式:

font: 12px/10px;
width: calc(100% - 20px);

所以,在这些观点上大部分是一致的,而且大多数争论都围绕着可能的解决方案。 calc()问题看起来已经有足够的共识来推进了。 基本上:不要接触 calc,并将calc()变量视为字符串插值。 这就是 Sass 的做法,尽管它需要calc()的插值语法,我认为我们不需要。

font部分的解决方案变得更加棘手,主要的解决方案是:

  1. 默认情况下,所有内容都需要括号(第一次尝试 - 几乎已实现,但社区拒绝了)
  2. 翻转strictMath开关(已添加而不是将其设为默认值,以及@seven-phases-max 的建议),然后明确地进行所有数学运算。 从技术上讲,对于目前大多数人来说,这是一个可能的解决方案,但是......这个问题出现得如此频繁,而且我们知道,从心理上讲,任何系统的新手都可能保留任何默认值,所以这是有问题的。 并不是每个开发人员都可以更改他们的构建设置,尤其是在团队中。
  3. 从本质上改变 Less 中的除法运算符。 线程中的主要竞争者是./ ,它有效但看起来有点奇怪。 \在这一点上是未知的,没有研究。 可以工作,可能会导致与转义的未知冲突。 它的语法更简洁,但(可能但未知)风险更高。 如果有人花时间演示这不会引起冲突,即提供转义和数学混合的示例,解析器可以清楚地区分两者,那么它仍然是一种可能性。 所以它只需要工作。 @thany ,如果您或其他人

我认为,为了简化这个线程,我们应该从这里开始,只关注#3 。 我发布 Sass 示例主要是出于好奇,但我不相信这些解决方案是好的或完全解决问题,并且它们在概念上与 Less 不兼容。 争论要求0 + 1/2的有效性不会让我们有任何进展。

所以,有了calc()一个很好的解决方案,这让我们在大多数发布的问题上解决了 50% 的问题,我建议只在短期内关注这个问题:

如果要更改 Less 除法运算符,它应该更改为什么?

  • ./ - 这是否像我觉得的那样尴尬,或者人们认为这很好?
  • \ - 没有研究和证明,以及解析器遵循的伪代码,这不会向前推进。 我个人更喜欢它,如果它可以被证明是安全的。
  • 其他替代品?

老实说,如果我们更改calc()并更改/ ,我认为我们会在 Less 中消除 99% 的数学噪音。

大家好,我修复了calc() - https://github.com/less/less.js/pull/3162

当我想出一个无需太多附加代码即可工作的解决方案时,我有点惊讶。 基本上,我们已经有了strictMath开关的代码,并且如果它在括号之外,则检查表达式以不计算数学,所以我只是在调用时添加了一个额外的开关以在计算calc()关闭数学

查看https://github.com/less/less.js/pull/3162/files#diff -a94aaffd78b1d3c5eda7a42d5be1ca0d 和https://github.com/less/less.js/pull/3162/files#diff -4e696271823c916903a64

测试是否足够?

@马修院长:咖啡:

测试是否足够?

根据 PR 中的评论添加请进行如下测试:

foo: 1 + 2 calc(3 + 4) 5 + 6; // expected result: 3 calc(3 + 4) 11;

还有一个小问题:这个修复显然引入了与 #1627 相同的问题,即

<strong i="13">@a</strong>: floor(1.1);
<strong i="14">@b</strong>: floor(1 + .1);

div {
    foo: calc(<strong i="15">@a</strong> + 20%); // ok
    bar: calc(<strong i="16">@b</strong> + 20%); // error: invalid floor arguments
    baz: @b;             // ok
}

但是对于calc来说,我想这很好(毕竟没有其他简单的方法可以修复它,而calc使用 vars 时,只需在文档中添加一个通知,以记住lazy-eval。

还有一个小问题:这个修复显然引入了与 #1627 相同的问题

接得好!

每次调用切换上下文mathOn属性可以解决这个问题,类似于您在 PR 中的评论。 我为float(1 + .1)添加了一个测试,它通过了!

每次调用切换上下文 mathOn 属性可以解决这个问题,类似于您在 PR 中的评论。 我已经 > 添加了一个通过的 float(1 + .1) 测试!

:) 不, -sm: off必须存在“地板”错误。 请参阅我在 PR 中的最新评论。
恢复只处理1 + 2 calc(3 + 4) 5 + 6类的事情。

:) 不,“地板”错误必须在 -sm: off 时出现。

为什么? calc()任何函数都应该是 Less 函数。 即使它们不是,我知道 calc() 中没有 CSS 原生函数可以采用原始数学表达式。 预期的结果是评估 vars 和 Less 函数,但将原始函数留在calc()

旁注:我做了一个分支实验,将/\作为 Less 中的除法运算符。 已经有很多用于转义的测试(我添加了更多,以解决:#3160),并且它们仍然可以正常工作,并且在切换运算符时数学可以正常工作。 我没有看到任何内在的冲突。 分支在我的叉子上: https :

回复:嵌套函数

为了这:

div {
    bar: calc(floor(1 + .1) + 20%);
}

作为开发人员,预期的结果应该是:

div {
    bar: calc(1 + 20%);
}

这正是现在发生的事情(有了这些变化)。 它不应该抛出错误。

@马修院长
不,你写的方式,这个:

foo: unit(1/2, px);

with -sm:on将编译为:

foo: .5px;

^-错了。
嵌套函数也一样。 此外,大多数函数通常不能将算术表达式作为参数的事实并不是违反-sm: on的理由;
因此在-sm: on两行:

foo: floor(1 + .1);
bar: calc(floor(1 + .1) + 20%);`

必须抛出一个错误(这就是在提交中被破坏的东西)。

你在说什么?

unit(1/2, px)-sm:on

ERROR: error evaluating function `unit`: the first argument to unit must be a number. Have you forgotten parenthesis?

calc(floor(1 + .1) + 20%)-sm:on

ERROR: error evaluating function `floor`: argument must be a number

检查分支。 试试看。

可能对审查代码更有帮助的一件事是,如果您不确定某些内容是否会产生不正确的输出,请验证它。 或者让我尝试一个特定的输入来验证它是否按预期工作。 或者,如果您不确定它是如何/为什么起作用的,请提出问题。 在不知道它是否没有帮助的情况下称其为错误。

我的道歉。 我想我错过了对这部分的间接控制。

检查分支。 试试看

我不能,对不起。

我的道歉。 我想我错过了这部分的间接控制。

不用担心。 解决这个问题后,它看起来像您期望的那样工作吗?

解决这个问题后,它看起来像您期望的那样工作吗?

是的,到目前为止我无法想象那里有任何其他可疑的事情。

@马修院长
从本质上改变 Less 中的除法运算符。 线程中的主要竞争者是 ./,它有效但看起来有点奇怪。 \ 在这一点上是未知的,没有研究 [...] @thany ,如果您或其他人是这个的粉丝,那么这就是所需的工作。 我们最不想做的就是将休息时间移到其他地方。

实际上完全没有。 我建议将\运算符作为未通过后的最后手段,试图让 LESS只做自己的数学运算。 如果需要一个新的除法运算符... 那么, calc()还可以执行加法、减法和乘法。 那些新的运营商? 我认为这是不切实际的。 新的除法运算符可能是字体、背景和边框半径等问题的解决方案,但它不是 CSS 数学的解决方案。

我仍然认为真正的解决方案是让 LESS 了解上下文。 它应该(是的,在这里我再次使用我的“应该”,我必须使用什么其他词?...)知道calc()是一个 CSS 函数,它应该只计算 CSS 不能做的数学. 但是floor()在 CSS 中不存在,因此它必须评估(完全)以不喷出无效的 CSS。 我认为这之前已经提到过,但措辞不同。

我仍然认为真正的解决方案是让 LESS 了解上下文。 它应该(是的,在这里我再说一遍我的“应该”,我还必须使用什么其他词?...)知道 calc() 是一个 CSS 函数,它应该只计算 CSS 不能执行的数学运算。 但是 floor() 不存在于 CSS 中,因此它必须(完全)评估以不喷出无效的 CSS。 我认为这之前已经提到过,但措辞不同。

足够公平: \ ,但就上下文而言,根据您的其他帖子,我可以保证这是一个比您想象的要复杂得多的问题。 你真的必须把它归结为:

12px/10px  // Is this division, or not?
10px/1.5 // is this division, or not? 

如果您想肯定地将/保留为除法运算符,以模仿calc() ,并且不让它模棱两可,那么您绝对需要确保/在括号(除了calc()例外)。 这将提供可预测的背景。

这个帖子开头的那个建议也是有可能的,并且得到了一些有力的支持。 本质上,默认设置是除除法之外的所有数学都支持括号外(再次,除了calc() ,现在是 3.0+ 的情况)。 也许这就是要走的路。 这将允许:

font: 10px/1.5;   // not division
font: (10px/10);  // division, result is 1px
font: 10px+15px/1.5;   // addition but not division, result is 25px/1.5
font: (10px+15px/1.5);  // result is 20px

事实是, 10px+15px/1.5的结果对于开发人员来说可能仍然难以理解,除非它在括号中,否则表达式似乎会“评估一半”。 如果我们继续并在默认情况下打开严格的数学,它可能会很好。 它甚至更不模棱两可。 [耸肩]无论哪种方式,将数学包装在某种上下文中是消除歧义的方法,也是除更改除法运算符之外的除法的唯一方法。

社区必须从根本上决定方向。 此线程中有可行的选项。 每个都有缺点。 每个都有痛点。 没有人会完全达成共识。 但 IMO 中的任何一个都比目前的情况好。 只需要吞下那个药丸。

最后呼吁作出决定

因此,为了解决不可能的问题,我想建议我们这样做(参考 3 年前的评论。)

--strict-math 3 个设置

  1. 离开
  2. 分配
  3. 严格(别名on用于反向兼容)

要解决争论,请允许--strict-math=division开关执行以下操作:

  1. 不要只用括号外的/字符进行除法。 例如border-radius: 55px / 25px; --> 没有数学(是的,这是有效的 CSS)
  2. 允许使用两种不同的方法进行除法:
    一个。 .前缀 - border-radius: 55px ./ 25px;
    括号- border-radius: (55px / 25px);
  3. 两种形式都在括号中有效 - 例如border-radius: (55px ./ 25px);将有效

因此,作为开发人员,如果您觉得一个版本不是您的偏好,您可以使用另一个。 有些人可能不喜欢使用括号; 有些人可能不喜欢使用修改后的除法运算符。 适合每个人的东西。 对于使用 CSS 中现在广泛使用的语法的 Less 新手来说,不会再有令人不快的惊喜, /用于fontbackgroundborder-radius@media查询、CSS 网格属性,以及将来可能更多。

下一步

我建议将此作为一个选项进入 PR,然后,正如所讨论的那样,将其切换为未来主要版本的默认设置

@马修院长

即句点的行为有点像转义序列的反相?
不错的主意,真的……

考虑到所有因素,_可能_是最干净的解决方案之一。

@rjgotten从这里开始: https :

我仍然在其中一个测试中遇到一个奇怪的错误,它似乎将维度节点之一转换为操作节点(然后抛出错误,因为它无法在操作节点上执行操作。它没有)这似乎是一个解析问题,因为另一个不在strictMath: division下运行的测试工作正常。想检查一下,看看是否可以提供帮助?

我想做的是关闭这个问题并创建处理剩余数学问题的新问题。 具体来说:

  1. 处理除法和strictMath: 'division'功能。
  2. 处理混合单位的数学。 参见: https :
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

matthew-dean picture matthew-dean  ·  6评论

Oskariok picture Oskariok  ·  6评论

rejas picture rejas  ·  6评论

renoth picture renoth  ·  6评论

vecerek picture vecerek  ·  5评论