unquote()包裹CSS原生函数是危险解法,因放弃编译期校验与单位处理,导致运行时单位冲突或语法错误;应直接写原生CSS语法,如height: min(100vh, 50em);。

直接用 unquote() 包裹 CSS 原生函数(如 min()、max()、clamp())是常见但危险的“解法”——它能绕过 Sass 编译器报错,却会把计算逻辑完全推给浏览器,失去编译期类型校验和单位预处理能力,极易在运行时出错。
为什么 unquote("min(100vh, 50em)") 不是真正解决问题
这个写法让 Sass 把字符串原样输出为 CSS,看似“不报错”,实则放弃所有编译期保障:
-
unquote()不做任何单位转换或合法性检查,min(100vh, 50em)中的vh和em仍由浏览器解析,而浏览器不支持跨单位比较,最终可能被忽略或降级为默认值 - 若该表达式嵌套在
calc()或其他函数中(如calc(unquote("min(100vh, 50em)") + 10px)),CSS 语法直接非法 - 无法与 Sass 变量组合使用:
unquote("min(#{$height}, #{$width})")在旧版 Sass 中会提前拼接字符串,导致变量未求值或引号污染
正确区分:哪些 CSS 函数必须用原生写法,哪些可保留 Sass 处理
关键看函数是否参与编译期计算:
- 纯运行时函数(
min()、max()、clamp()、toggle())——必须写成原生 CSS 形式,不加引号,不进 Sass 函数调用栈 - 单位无关的数学函数(
calc())——可安全混用 Sass 变量,但需确保内部单位合法:calc(#{$base} * 1rem + 2px)是 OK 的;calc(#{$a}vh + #{$b}em)是危险的 - 颜色/滤镜函数中部分参数(
filter: invert(var(--p)))——不能用 Sassinvert($color)替代,因后者要求编译期已知颜色值,而var(--p)是运行时才存在
遇到 min()/max() 单位冲突错误时的实操路径
当看到 “Incompatible units: vh and em” 这类报错,说明你误用了 Sass 自带的 min() 函数(它只接受兼容单位),而非 CSS 原生函数:
立即学习“前端免费学习笔记(深入)”;
- 删掉所有对
min()、max()的@function调用或#{}插值包裹 - 直接写 CSS 原生语法:
height: min(100vh, 50em);,不要加引号、不要用unquote()、不要试图在@if中判断 - 如果需动态生成值,用 CSS 自定义属性 +
calc()组合:--h1: 100vh; --h2: 50em; height: min(var(--h1), var(--h2)); - 确认构建工具链未启用旧版
node-sass(它会强制解析所有函数),应使用sass(Dart Sass)并关闭functions选项(默认已禁用)
容易被忽略的兼容性断层点
很多人以为升级到 Dart Sass 就一劳永逸,但仍有两处隐性断层:
-
@use "sass:math"中的math.min()仍受单位限制,它不是 CSSmin()的别名,而是纯编译期函数,不可混用vh/em - Vue / Vite 项目中若配置了
css.preprocessorOptions.sass.additionalData注入全局变量,这些变量无法穿透到min()等原生函数内部——它们只存在于 CSS 字符串层面


















