将单位类型附加到 Sass 中的计算结果

Posted

技术标签:

【中文标题】将单位类型附加到 Sass 中的计算结果【英文标题】:Append unit type to the result of a calculation in Sass 【发布时间】:2012-12-04 00:46:24 【问题描述】:

我最近一直在将我的 CSS 重构为 SASS 样式表。我在 VS2012 中使用 Mindscape Web Workbench extension,每次保存 SCSS 时都会重新生成 CSS。我从类似这样的代码开始:

/* Starting point: */
h1  font-size: 1.5em; /* 24px ÷ 16px */ 

然后我尝试先将其重构为:

/* Recfator: */
h1  font-size: (24px / 16px)em; 

但不幸的是,这会产生:

/* Result: */
h1  font-size: 1.5 em;               /* doesn't work, gives "1.5 em" */

注意额外的空间,我不想在那里。我已经尝试了几种替代方法,这里有一些:

h1  font-size: (24/16)em;            /* doesn't work, gives "1.5 em" */
h2  font-size: 24 / 16em;            /* doesn't work, gives "24/16em" */
h3  font-size: (24px / 16px) * 1em;  /* works but "* 1 em" feels unnecessary */
h4  font-size: (24em) / 16;          /* works, but without "px" it's not 
                                          really conveying what I mean to say */

我也尝试过这些带有变量的变体(因为无论如何我都想要这些变体),但这并没有太大改变这种情况。为了使这个问题中的示例保持流畅,我省略了变量。但是,我很乐意接受依赖于使用变量的解决方案(以干净的方式)。

我已经浏览了relevant SASS documenation on '/',并意识到这对于 SASS 来说是一个艰难的问题,因为“/”字符在基本 CSS 中已经有了意义。无论哪种方式,我都希望有一个干净的解决方案。我在这里遗漏了什么吗?

PS。 This blogpost 确实提供了一种解决方案,使用用户定义的函数。不过,这似乎有点重,所以如果有符合我上述尝试的“更清洁”的解决方案,我很感兴趣。如果有人可以解释“函数方法”是更好(甚至唯一)的解决方案,那么我也会接受它作为答案。

PS。 This related question 似乎是同一件事,尽管有人特别想做进一步的计算。 The accepted answer there 是我的第三个解决方法(乘以 1em),但如果我愿意放弃进行进一步计算的能力,我很想知道是否有不同的(更清洁的)方法。也许上述问题中提到的方法(“插值”)对我有用?


底线:如何将单位类型(例如 em)干净地附加到 SASS 中的计算结果中?

【问题讨论】:

做数学有什么好处(除了较慢的编译和可能较低的可读性)?并非每个浏览器都以 16px 字体大小开始(从历史上看,Opera 使用的基本字体大小比其他浏览器更小……而且众所周知,用户会故意增加或减少他们的字体大小)。 一旦我用变量替换数字,数学将显示意义和/或意图,使其自我记录而不是“魔术”。正如我在问题中提到的,我在示例中省略了变量以使其保持简单。 你还没有回答这个问题:做数学对你有什么好处?无论您最终使用什么(变量与硬编码值)24px / 16px * 1em 的可读性都低于1.5em 你通过重新打开这个问题对世界各地的 Sass 作者造成了极大的伤害。它现在是谷歌上的最高结果。您的“首选方法”是将单位附加到数字的最糟糕的方法,并且只会在它不能按照他们期望的方式工作时引起混乱。 如果您不同意最受支持和接受的答案,您应该写一个更好的答案,而不是在 cmets 中大肆宣扬。 - 解释为什么/何时选择错误的工具和/或告诉人们我已经提到的一种方法是首选方法。 【参考方案1】:

将单位添加到数字的唯一方法是通过算术

执行连接(例如1 + px)或插值(例如#1px)之类的操作只会创建一个看起来像数字的字符串。即使您绝对 100% 确定您永远不会在另一个算术运算中使用您的值,您也不应该这样做

比不能执行算术运算更重要的是,您将无法将它们与其他需要数字的函数一起使用:

$foo: 1; // a number
$foo-percent: $foo + '%'; // a string

.bar 
    color: darken(blue, $foo-percent); //Error: "1%" is not a number!

$amount: "1%" 不是 `darken' 的数字

将数字转换为字符串不会有任何收获。始终使用算术(乘以 1 或加法 0)来添加单位:

$foo: 1; // a number
$foo-percent: $foo * 1%; // still a number! //or: $foo + 0%

.bar 
    color: darken(blue, $foo-percent); //works!

输出:

.bar 
  color: #0000fa;

这是我作为 Flexbox mixin 库的一部分编写的一个 mixin,如果你传入一个字符串,它会阻塞(对于那些不熟悉 Flexbox 的人,原始规范只允许 box-flex 属性的整数。flex: auto 或 @ 987654329@ 无法与类似的 box-flex 属性兼容,因此 mixin 不会费心尝试)

@mixin flex($value: 0 1 auto, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) 
    @if $legacy and unitless(nth($value, 1)) 
        @include legacy-flex(nth($value, 1));
    

    @include experimental(flex, $value, flex-support-common()...);


@mixin legacy-flex($value: 0) 
    @include experimental(box-flex, $value, $box-support...);

【讨论】:

有趣的事实:在这里找到你的答案后几秒钟(单位转换)我用谷歌搜索了 Sass 是否有一个 switch 结构,然后我登陆了这里:github.com/sass/sass/issues/554#issuecomment-18304635 计算几率,好先生。 :D 谢谢! 对于百分比和 sass 变量 $var,我使用:#$var#"%"。 可能会更改“将单位添加到数字的唯一方法是通过算术。” → “...是通过乘法。”会更清楚。我在所有地方都尝试了 addition,然后才意识到这正是 要做的...... @Atav32 实际上 addition 也是可能的,如果你有$foo: 1; 那么你可以使用$foo-percent: $foo + 0% 将其转换为像$foo * 1%这样的百分比 TL;DR $foo-percent: $foo * 1%;【参考方案2】:

您可以尝试以下任何一种:

font-size: $size * 1px;

font-size: $size + unquote("px");

$size 是您的计算结果。

【讨论】:

第二种方法对我来说效果很好。我发现unquote("px"); 是这里的关键。如果我们不应用unquotepx 将在引号内呈现,浏览器将无法正确呈现该值。因此应用unquote 是必不可少的。 注意字体大小:$size + px; (在 px 周围没有任何引号)也是可能的,这比第二种方法简单!请参阅下面的my answer【参考方案3】:

选择你喜欢的方法

$font: 24px;
$base: 16px;

无变量

.item1  font-size: #(24px / 16px)em; 

仅使用变量

.item2  font-size: #$font / $baseem; 

一个变量

.item3  font-size: #$font / 16pxem; 
.item4  font-size: #24px / $baseem; 

所有的输出

.item1  font-size: 1.5em; 
.item2  font-size: 1.5em; 
.item3  font-size: 1.5em; 
.item4  font-size: 1.5em; 

使用的方法叫interpolation #

【讨论】:

百分号可以使用同样的方法吗? SCSS 似乎在抱怨…… 百分号也必须使用插值法,例如#(24px / 16px)#"%"会输出1.5% 你永远不应该这样做。曾经。在任何情况下。这将始终为您提供一个字符串,这意味着您将永远无法在以后的数学运算中使用结果。 这里是 Sass 首席设计师! @cimmanon 是对的;这不是转换单位的稳健或惯用方式。 Sass 的单位是其算术的一部分,使用单位算术将有助于生成更好、更易于维护的样式表。 百分比你也可以使用#(24px / 16px)unquote("%")【参考方案4】:

我认为您问这个问题的原因是,在周围环境中,1 em = 16 px,并且您希望使用这种关系将目标字体大小从像素转换为 em。

如果是这样,正确的做法是将字体大小乘以缩放因子 1em / 16px,如下所示:

$h1-font-size: 24px;
$body-font-size: 16px;

$body-em-scale: 1em / $body-font-size;

h1 
  font-size: $h1-font-size * $body-em-scale;  // -> 1.5em

或者只是:

h1 
  font-size: $h1-font-size * (1em / $body-font-size);  // -> 1.5em

这也正是它在物理学中的工作原理:如果有 50 个 moles 的水,并且您想知道 grams 的重量有多少,则乘以您拥有的水量(= 50 mol) 与molar mass 的水 (&约; 18 g/mol) 找出你的水样重 50 mol × 18 g/mol &约; 900克。在 SASS 中将像素转换为 em 的工作方式相同:首先找出每个像素有多少 em,在您打算使用规则的上下文中,然后将 px 中的大小乘以该比率,以 em 为单位表示/px。


附言。当然,如果您要转换的单位具有 SASS 已经知道的固定比率,那么您可以简单地让它自动为您进行转换,使用“零加技巧”。例如,如果您想将字体大小从 px 转换为 cm,您可以简单地这样做:

h1 
  font-size: 0cm + $h1-font-size;  // -> 0.635cm

之所以有效,是因为 SASS 允许您将两个以兼容单位(如 px 和 cm)给出的值相加,并将以与总和中的 first 值相同的单位表示结果。这个技巧对 px -> em 不起作用的原因是这里的转换因子不是固定的,而是取决于周围的上下文,所以 SASS 不知道如何自动进行转换.

【讨论】:

也就是说,这个问题是现有问题的重复? (见:***.com/questions/15513395/…) @cimmanon:不完全是。该问题询问如何将单位附加到无单位数。这个是问如何在两个不同单位(px -> em)之间转换尺寸度量。 我们也有关于剥离单元的问题(请参阅:***.com/questions/12328259/…) @cimmanon:我想说的是,在这里随意剥离和附加单位是错误的。单位在那里for a reason,你真的应该和他们一起工作,而不是在做数学之前用黑客来剥离它们,然后再把它们粘回去。在没有固定比率的两个单位之间进行转换的正确方法是找出适合您情况的正确转换比率并乘以它。【参考方案5】:

添加单位的最佳方法是使用... * 1em... + 0em,其中em 是您想要获取的单位:

font-size: (24px/16px) + 0em; // ... + 0px for px
//or
font-size: (24px/16px) * 1em; 
//both produce: font-size: 1.5em;

这样,它将保留为 数字,以便您可以在数学运算或其他函数中使用它。

但是如果你想把结果作为一个字符串或者由于某种原因不关心结果的数值,你也可以这样简单地得到它:

font-size: (24px/16px) + em; //font-size: 1.5em; //em does not include quotations

此处无需使用unquote#(如其他答案所述)!

【讨论】:

以上是关于将单位类型附加到 Sass 中的计算结果的主要内容,如果未能解决你的问题,请参考以下文章

将 FMDB SQLite 结果附加到 Swift 数组

使用 Sass 将父选择器附加到末尾

将结果数据附加到 Parallel::ForkManager Perl 中的标量变量

将 for 循环的结果附加到 Laravel 中的 eloquent 输出

使用 JavaScript 将 ajax 的结果附加到文本区域

循环 LINQ 查询并将结果附加到 DataTable