css 使用 calc 的变量不更新

css vars which use calc don't update

从下面的笔中可以看出,css 使用 calc 的变量似乎不尊重变量的级联性质:

:root {
  --font-size-mult: 1;
  --font-size: calc(var(--font-size-mult) * 16px);
}

* {
  font-size: var(--font-size);
}

.large {
  --font-size-mult: 2;
}

预期的行为是文档中具有 .large class 的任何部分的字体大小都是常规 16px 的两倍。从示例中可以看出,如果我在 .large 中重新定义 font-size 变量,我会得到所需的行为,但这似乎违反直觉,因为 --font-size 的值已经是它需要的值解析为正确的值。

这似乎是我测试过的所有浏览器的情况,因此它可能是规范的一部分,但它似乎不太适合 CSS 的工作方式。我认为变量值将根据当前元素范围内的其他变量的值计算,而不是根据定义变量的范围计算。

https://codepen.io/Smilebags/pen/MrRKMY

这是预期的行为吗?应该是这样吗?

如果您将 calc 移动到您调用变量的位置,而不是您声明它们的位置,它将更新。 演示:

:root {
  --font-size-mult: 1;
  --font-size: 16px;
}

* {
  font-size: calc(var(--font-size-mult) * var(--font-size));
}

.large {
  --font-size-mult: 2;
}

是的,这是预期的行为,实际上完全尊重自定义属性的级联性质。来自 section 2.2 of the spec:

It is important to note that custom properties resolve any var() functions in their values at computed-value time, which occurs before the value is inherited.

这意味着出现在根元素上的自定义 属性 --font-size 的值实际上是 calc(1 * 16px),而不是 calc(var(--font-size-mult) * 16px),因为 var(--font-size-mult) 表达式在为根元素计算 --font-size 时计算。

此计算值 calc(1 * 16px) 随后由后代继承。您为任何后代 --font-size-mult 设置的任何新值都将被忽略(除非存在对它的其他引用)。

这应该是预期的行为吗?好吧,我只能告诉你规范声称这是防止祖先和后代之间循环引用所必需的。在与上面引用的句子相同的段落中:

In general, cyclic dependencies occur only when multiple custom properties on the same element refer to each other; custom properties defined on elements higher in the element tree can never cause a cyclic reference with properties defined on elements lower in the element tree.

最后,虽然 Kriszta 的回答演示了将 calc() 与自定义属性一起使用的正确方法(考虑到继承),但您应该使用 rem 单位而不是完全使用自定义属性,因为该单位是专门为此制作的用例。