scss中无法对css变量var(--size)直接进行算术运算,因其在编译期仅为字符串占位符;所有数值运算须在scss变量或纯数字上进行,css层缩放需依赖calc()配合单位处理。

SCSS里不能对var(--size)做算术运算
直接写width: var(--size) * 2会编译失败——CSS变量在SCSS编译期只是字符串占位符,var(--size)不会被解析为数值,更无法参与乘除。浏览器运行时才解析var(),但那时SCSS早已退出舞台。
常见错误现象:font-size: var(--base-font) * 1.2 编译报错 SyntaxError: Invalid CSS after "var(--base-font) ",或静默输出无效CSS。
- SCSS编译器看到
var(--x)就原样放行,不拆解、不推导、不校验单位 - 所有运算必须发生在SCSS变量(如
$size: 16px)或纯数字(如16)上 - 若想让CSS变量参与缩放,得靠
calc()在运行时算,且必须确保插值后格式合法
calc()里拼px要先剥离单位再插值
比如想把--size的值放大1.5倍并转成px,不能写calc(var(--size) * 1.5)(--size若存的是"16",calc(16 * 1.5)成立;但若存的是"16px",calc(16px * 1.5)非法)。
安全做法是:SCSS层只处理纯数字,CSS层用calc()补单位:
- 定义CSS变量时存纯数字:
--size: 16(不是16px) - 使用时统一加单位:
font-size: calc(var(--size) * 1px) - 需要缩放:
font-size: calc(var(--size) * 1.5 * 1px)
如果变量来源不可控(比如从JS注入或map lookup),先用if(unitless($val), $val, $val / 1px)归一化为数字再插值。
用#{}插值拼calc()时,别让/被误判为除法
写width: calc(#{($a / $b)} * 1px)没问题,但写line-height: #{$ratio} / #{$base}可能出事——SCSS看到/在变量之间,会尝试做除法;而你本意可能是输出line-height: 1.5 / 16px这种CSS原生语法。
正确写法是用插值包裹整个片段:
- 错误:
line-height: $ratio / $base(SCSS当除法,且单位不匹配易报错) - 正确:
line-height: #{$ratio} / #{$base}(纯文本拼接,不运算) - 更稳:
line-height: #{unquote($ratio + ' / ' + $base)},避免引号干扰
注意:unquote()只去引号,不改变内容;#{}内不能嵌套#{},也不能调用函数(如#{round($x)}可以,但#{unit($x)}不行,因unit()返回字符串,插值后类型已失)。
从map或函数取值时,单位状态必须显式判断
比如配置表$typo: (h1: 24px, h2: 20px, body: 16),取map-get($typo, body)可能返回16(无单位)或16px(带单位),后续直接* 1.2会失败。
必须标准化:
- 用
type-of()确认是否为number类型 - 用
unitless()判断是否无单位,再决定是否+ px或/ 1px - 推荐封装:
@function safe-px($val) { @return if(unitless($val), $val + px, $val); }
真正容易被忽略的是:CSS变量本身不携带类型信息,JS注入style.setProperty('--size', '16px')和'16'在SCSS里无法区分——所有var()都是字符串,运算逻辑只能靠约定和预处理守住。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











