从下面的笔中可以看出,使用 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;
}
Run Code Online (Sandbox Code Playgroud)
预期的行为是文档中任何具有 .large 类的部分的字体大小都是常规 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;
}
Run Code Online (Sandbox Code Playgroud)
是的,这是预期的行为,实际上完全尊重自定义属性的级联性质。来自规范的第 2.2 节:
请务必注意,自定义属性会在计算值时解析其值中的任何 var() 函数,这发生在继承值之前。
--font-size这意味着根元素上显示的自定义属性的值实际上是calc(1 * 16px),而不是calc(var(--font-size-mult) * 16px),因为在计算根元素var(--font-size-mult)时会计算表达式。--font-size
然后,该计算值calc(1 * 16px)被后代继承。您为任何后代设置的任何新值--font-size-mult都将被忽略(除非存在对其的其他引用)。
这应该是预期的行为吗?好吧,我只能告诉你,规范声称这是为了防止祖先和后代之间的循环引用所必需的。在与上面引用的句子相同的段落中:
一般来说,只有当同一元素上的多个自定义属性相互引用时,才会发生循环依赖;在元素树中较高的元素上定义的自定义属性永远不会导致对在元素树中较低的元素上定义的属性的循环引用。
calc()最后,虽然 Kriszta 的答案演示了考虑继承的情况下使用自定义属性的正确方法,但您应该完全使用 rem 单元而不是自定义属性,因为该单元是专门针对此用例而制作的。