SASS:不兼容的单位:“vw”和“px”。

40

如何解决不兼容的单位问题?

@mixin square-size($size, $min: $size, $max: $size) {
  $clamp-size: min(max($size, $min), $max);
  width: $clamp-size;
  height: $clamp-size;
}

输入为:

@include square-size(10vw, 40px, 70px);

问题:

Incompatible units: 'vw' and 'px'.
node_modules\@ionic\app-scripts\dist\util\helpers.js:253.replace(/&/g, '&')

但如果我使用calc(1vw-1px),它就可以正常工作(没有单位问题)。 例如:max(calc(1vw-1px))不起作用,因为max函数需要一个数值参数。

在我的情况下,我想要一个mixin来将元素的大小平方。包括clamp。 min-widthmax-width等不起作用,因为它会变成矩形或椭圆形,而不保持纵横比。 我想要一个具有动态size但带有minmax大小的元素。

我知道动态单位vw(视口单位)必须在sass编译后出现。因此,无法将其转换为固定单位。 但是难道就没有办法吗?


1
由于Sass是在服务器上编译的,而不是在浏览器中 - vw(和其他相对单位)无法转换为可以进行数学计算的值。calc()是由浏览器计算的,而不是Sass。因此,您需要获取绝对值以便在Sass中进行计算,或将您的方程式转换为calc()表达式以在浏览器中计算。 - Flying
8个回答

40

我使用calc函数成功修复了React SASS中的错误。

font-size: calc(max(8vw, 30px));

26
如果您无法通过其他方式解决它,SCSS有一个函数可以忽略引号中的内容:
width: unquote("max(50px, 5rem)");

这将在不带引号的情况下编译,且为有效的 CSS。

width: max(50px, 5rem);

在你的scss文件中加入这些内容会显得有些奇怪,但这是确保现代CSS不会干扰你的scss函数的绝佳方法。


只有这个解决方案适用于我。虽然不是最漂亮的,但它能完成工作 ;) - Rorrim

16

问题

CSS以前没有自己的min()max()函数,在它们出现之前SASS有一个编译时版本。由于SASS不能实时运行,因此它无法确定10vw40px哪个更大 - 因此会出错。

解决方法

由于SASS区分大小写CSS不区分大小写,您可以通过调用MIN()MAX()来强制解析器使用CSS版本的min或max。如果您需要在MAX()内恢复SASS解析(例如引用SASS变量),只需将SASS代码用#{...}括起来即可。

这里是演示修复后的代码:

@mixin square-size($size, $min: $size, $max: $size) {
  /* $clamp-size: min(max($size, $min), $max); */
  $clamp-size: MIN(MAX(#{$size}, #{$min}), #{$max});
  width: $clamp-size;
  height: $clamp-size;
}

祝你好运!


我喜欢这种解决方法的想法,而不是 calc() 的技巧,但我的 stylelint 设置将其压缩为小写,然后致命错误又出现了……所以,还是使用 calc() 吧! - squarecandy

9

您需要绕过scss编译器并使用字面量。

@mixin square-size($size, $min: $size, $max: $size) {
  $clamp-size: #{'min(max(#{$size}, #{$min}), #{$max})'};
  width: $clamp-size;
  height: $clamp-size;
}

1
这是正确的解决方案,但我第一次忽略了它,因为我看不到哪些是相关的更改。 - mb14

3

试一下

在sass中使用minmax时,如果出现不兼容的单位错误,您可以简单地将值放在引号中,这样它就会通过。

min(10vw, 20px) 变为 "min(10vw, 20px)"

这对其他函数也适用。

如果您在计算中使用变量,您需要在变量上使用#{}来使其通过。

$a: 10px;
$b: 25%;

.mydiv {
  width: calc(#{$a} - #{$b});
}

#{} 将它们转换为字符串,这样在编译时,Sass 就不会使用它们进行算术计算。


1
您可以使用最小宽度/高度和最大宽度/高度来避免混合单位,像这样进行操作:
@mixin square-size($size, $min: $size, $max: $size) {
  min-width: $min;
  max-width: $max;    
  min-height: $min;
  max-height: $max;    
  width: $size;
  height: $size;
}
.class {
    @include square-size(10vw, 40px, 70px);
} 

谢谢你的回答。但这恰好是我当前的实现方式。但正如我上面所写的,它在某些情况下会导致矩形或椭圆形。因为min-widthmin-height以及max-widthmax-height没有保持纵横比。如果上述描述中的信息不清楚,我很抱歉。无论如何,还是谢谢。 :) - Domske
你尝试运行过它吗?它总是会产生方块形状,再试着看看 :) 这里有一个笔记例子:https://codepen.io/jakob-e/pen/REBzKw - Jakob E

0
在大多数情况下,您可以使用以下方式: width: clamp(320px, 78vw, 78vw); 等同于: width: min(320px, 78vw); 但其中一个值必须是非动态的。

0

为此,我们可以使用 SCSS 的 @include

.foo {
  @include square-size(10vw, 40px, 70px);
}

使用更好的 CSS 函数 "clamp":

.foo {
    width:clamp(10vw, 40px, 70px);
    height:clamp(10vw, 40px, 70px);
}

问题在于,如果您在整个项目中使用了SCSS,则由于上述错误,SCSS无法编译clamp()、min()或max()。 - Andrew Lazarus
这是纯CSS。它运行良好。SCSS没有抛出错误。白白对我打负号。 - Dmitry Shashurov
你所写的是纯CSS,但OP正在询问SCSS - 你的代码需要作为内联或单独的.css文件。 - Andrew Lazarus
我在我的SCSS中使用了这段CSS代码,它运行良好,编译器没有问题。有人认为SCSS中有解决方案,但在CSS中只是一个表面的解决方案——更容易、更好、更优雅! - Dmitry Shashurov
我的scss出现了错误,因为CLAMP是一个scss函数,它要求比css中的3个更少/更多的选项。如果您正在运行旧的scss,则有许多现在对于现代css来说已经不相关的函数,但由于将它们解释为函数而失败。更新SCSS有时可能会破坏项目,因此unquote()函数是一种在scss中包装css clamp的方法,而无需处理魔鬼。 :) - Andrew Lazarus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接