PAYATHON 2026

CSS calc() 使用变量时如何兼容不同浏览器?

数据阿明

表达式 30px / 720px 需要浏览器支持两个带单位长度相除。这属于 CSS typed arithmetic,浏览器支持情况可能因版本而异。因此,含 var(--w) 的写法在不同浏览器中可能表现不同。var() 会将自定义属性的值代入计算,但不会绕过 calc() 的类型规则。MDN:calc() 与 typed arithmetic;CSS Values and Units Level 4

为什么看起来像 100%

示例中的两种写法分别是:

calc(30px / 720px * 100vw)
calc(var(--w) / 720px * 100vw)

当 --w 是 30px 时,代入后的数学表达式相同。不过,calc(30px / 720px * 100vw) 本身也包含长度除以长度的运算,部分浏览器可能不支持这类 typed arithmetic。如果计算结果导致 width 声明无效,浏览器可能采用该属性的默认或继承行为,使块元素看起来像是占满了容器。这不一定表示计算结果真的等于 100%。

提问中提到的浏览器差异与 typed arithmetic 支持不足相符,但缺少浏览器版本和最小复现,无法确认具体是哪种浏览器或版本导致问题。要定位原因,可以在目标浏览器和版本中分别检查两个表达式的计算结果,并确认使用它们的 CSS 属性。

可选的兼容写法

如果这个值表示用于缩放视口宽度的比例,可以单独提供无单位比例,再乘以 100vw,以避开长度除以长度的运算:

.element {
  --w-scale: 0.0416667; /* 30 / 720 */
  width: calc(100vw * var(--w-scale));
}

如果比例需要动态变化,应在设置比例的地方同时提供相应的无单位数值。仅靠 CSS 旧版 calc(),无法通用地把任意长度值转换成无单位比例。

如果 --w 可能保存颜色、字符串等不同类型,就不要把同一个自定义属性既用作长度输入,又用来保存任意内容。应为参与数学运算的长度或比例另设专用属性,并将颜色、字符串等值分别保存在各自的属性中。CSS 自定义属性保存的是 token 序列;值只有在具体使用位置符合属性和运算的类型要求时才有效。

需要保留 --w: 30px 时

可以继续使用原表达式,但需要浏览器支持相应的 typed arithmetic:

.element {
  --w: 30px;
  width: calc(var(--w) / 720px * 100vw);
}

这无法作为旧浏览器通用的兼容方案。如果必须覆盖不支持该运算的浏览器,又不能提供比例值、采用 Case 3 或使用 JavaScript,那么仅凭一个可能包含不同类型内容的 --w,无法通过通用且可靠的 calc() 改写来实现。需要调整数据接口,分别提供长度值和比例值,并在实际目标浏览器中验证。

备注:内容仅供参考。