<p>Less 会提前计算 calc() 中的表达式,需用 ~"calc(100% - 20px)" 原样输出;~"" 是唯一可靠转义方式,支持变量插值 ${@var},其他方法如反斜杠或 unit() 均无效。</p>

Less 会把 calc() 里的表达式当成数学运算提前计算
这是 Less 编译器的默认行为:只要看到类似 calc(100% - 20px) 这种结构,它就会尝试解析并执行减法,结果往往是 calc(80%) 或直接报错(比如单位不匹配时)。你本意是让这个字符串原样输出到 CSS 中,但 Less 捕获了它。
根本原因在于 Less 的表达式解析器把 calc() 当作普通算术上下文,而不是 CSS 函数字面量。所以不能靠“写对语法”来绕过,得明确告诉 Less:“别碰这部分”。
- 最稳妥的方式是用波浪线引号
~"..."包裹整个calc()调用,例如:width: ~"calc(100% - 20px)"; -
~""是 Less 的“转义字符串”语法,表示内容不参与计算、不解析变量、不展开插值,原样输出 - 注意:引号必须是英文双引号或单引号,且
~紧贴引号,中间不能有空格(~ "..."会失效) - 如果里面要拼接 Less 变量,得用插值
${},且整个字符串仍需包裹在~""中,例如:~"calc(100% - ${@gap})"
为什么不用反斜杠 \ 转义括号或减号
有人试过写 calc\(100\% - 20px\) 或 calc(100\% - 20px),但这些在 Less 中无效。Less 不支持对 CSS 函数内部字符做局部转义,\ 主要用于字符串内转义引号或反斜杠本身,对函数调用边界无影响。
-
\calc(100% - 20px)会被识别为一个叫\calc的非法标识符,编译失败 - 单独给
%加反斜杠(如100\%)只影响百分号解析,不阻止整个表达式被计算 - Less 的转义机制是“全有或全无”,
~""是唯一能完整隔离calc()上下文的方案
使用 ~"" 后的兼容性与注意事项
生成的 CSS 完全符合标准,所有浏览器都能正确解析 calc(),这点无需担心。真正要注意的是 Less 层的写法约束:
立即学习“前端免费学习笔记(深入)”;
- 不能在
~""内部写未定义变量,比如~"calc(100% - @missing-var)"—— Less 不会展开,但也不会报错,结果就是字面量输出,容易埋坑 - 如果需要动态单位(如
@base: 16px;),必须显式插值:~"calc(100% - ${@base})",否则@base就是纯文本 - 嵌套 calc(如
calc(calc(100% - 20px) / 2))同样适用,整个外层用~""包住即可 - PostCSS 或其他构建工具后续处理时,不会因为
~""产生额外字符 —— 它只在 Less 编译阶段起作用,输出就是干净的calc(...)
替代方案:用 unit() 或字符串拼接?
有人想绕开 ~"",改用 Less 内置函数,比如 unit(100, "%") 配合 + 拼接,但这非常脆弱:
-
unit(100, "%") + " - " + unit(20, "px")输出是"100% - 20px",不是函数调用,少了calc()外壳 - 强行加字符串:
"calc(" + unit(100, "%") + " - " + unit(20, "px") + ")",虽然能凑出字面量,但可读性差、易出错,且无法享受~""的语义清晰性 -
unit()本身不解决计算拦截问题,它只是单位转换工具,和calc()的逃逸需求无关
真正需要的不是“怎么拼字符串”,而是“怎么禁用 Less 的表达式求值”——~"" 就是为此设计的,没有更轻量或更可靠的替代。


















