70

我最近一直在将我的 CSS 重构为 SASS 样式表。我正在使用 VS2012 的Mindscape Web Workbench 扩展,每次保存 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 */

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

我已经浏览了有关 '/' 的相关 SASS 文档,并意识到这对 SASS 来说是一个艰难的文档,因为 '/' 字符已经在基本 CSS 中具有意义。无论哪种方式,我都希望有一个干净的解决方案。我在这里错过了什么吗?

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

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


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

4

5 回答 5

79

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

执行连接(例如1 + px)或插值(例如#{1}px)之类的操作只会创建一个看起来数字的字符串。即使你绝对 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或者flex: 30em不能与可比较的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...);
}
于 2012-12-16T21:23:43.140 回答
46

您可以尝试以下任一方法:

font-size: $size * 1px;

或者

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

$size你的计算结果在哪里。

于 2015-08-27T11:24:41.947 回答
21

选择您喜欢的方法

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

无变量

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

仅使用变量

.item2 { font-size: #{$font / $base}em; }

一个变量

.item3 { font-size: #{$font / 16px}em; }
.item4 { font-size: #{24px / $base}em; }

所有这些的输出

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

使用的方法称为插值 #{}

于 2012-12-20T16:44:42.707 回答
6

我假设您问这个的原因是因为在周围的上下文中,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摩尔水,并且你想知道它的重量是多少,你可以将你拥有的水量(= 50 摩尔)乘以摩尔质量水 (≈ 18 g/mol) 找出您的水样重 50 mol × 18 g/mol ≈ 900 克。在 SASS 中将像素转换为 em 的工作方式相同:首先找出每个像素有多少 em,在您打算使用规则的上下文中,然后将 px 中的大小乘以该比率,以 em 为单位表示/像素。


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

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

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

于 2015-06-26T21:53:31.940 回答
2

添加单位的最佳方法是使用... * 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

无需使用unquoteor #{}here(如其他答案中所写)!

于 2018-11-17T11:15:07.633 回答