使用calc的css变量不会更新

时间:2018-01-23 06:58:47

标签: css css-variables

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

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

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:1)

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

  

请务必注意,自定义属性会在计算值时解析其值中的任何var()函数,这些函数会在继承值之前发生

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

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

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

  

通常,只有当同一元素上的多个自定义属性相互引用时,才会出现循环依赖关系;在元素树中较高元素上定义的自定义属性永远不会导致在元素树中较低元素上定义属性的循环引用。

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

答案 1 :(得分:0)

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

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

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

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