CSS 变量默认值:如果尚未设置则设置
CSS variables defaults: set if not already set
我的 Web 组件使用 CSS 个变量。
这些变量需要默认值。
它们在许多文件中使用,所以我想提供默认值一次,而且只提供一次。
第一次尝试使文本变黑。为什么?
一次提供默认值的正确方法是什么?
.a {
--my-variable: red;
}
.b {
--my-variable: var(--my-variable, blue);
}
<div class="a">
<div class="b">
<span style="color: var(--my-variable);">text</span>
</div>
</div>
在 :root
中声明默认值,然后在选择器中覆盖。
:root {
--primary-color: red;
}
* {
color: var(--primary-color);
border: 1px solid var(--primary-color);
padding: 0.25rem;
margin: 0;
}
div {
--primary-color: green;
}
p {
--primary-color: blue;
}
<div>HI!</div>
…
<p>Bye!</p>
This first attempt makes the text black. Why?
因为这个 --my-variable: var(--my-variable, blue);
是无效的,因为你试图用它自己来表达同一个变量,这是不允许的,所以浏览器会简单地忽略它。然后稍后当使用 color: var(--my-variable);
时,颜色将回退到 initial
值,即黑色。
正确的方法是简单地在上层定义变量,它会被所有元素继承(就像@kornieff提供的解决方案)
Custom properties are left almost entirely unevaluated, except that they allow and evaluate the var() function in their value. This can create cyclic dependencies where a custom property uses a var() referring to itself, or two or more custom properties each attempt to refer to each other.
For each element, create a directed dependency graph, containing nodes for each custom property. If the value of a custom property prop contains a var() function referring to the property var (including in the fallback argument of var()), add an edge between prop and the var. Edges are possible from a custom property to itself. If there is a cycle in the dependency graph, all the custom properties in the cycle must compute to their initial value (which is a guaranteed-invalid value).
为了补充前面的答案,在某些情况下您可能不想在全局 :root
范围内声明变量。例如,当您创建一个可重用组件时,您希望在本地声明其样式,而不依赖于全局项目样式。特别是如果您正在为其他开发人员构建库。
在这种情况下,解决方案是将一个变量名暴露给“外部世界”,并在组件内部使用不同的变量名。组件容器应该只是将可选的外部变量映射到内部变量,并设置其默认值:
.my-component-container {
/* map optional "external" variables to required "internal" variables */
--my-variable-inner: var(--my-variable, blue);
}
.my-component-container .my-nested-element {
color: var(--my-variable-inner);
}
.my-component-container .my-other-nested-element {
border-color: var(--my-variable-inner);
}
这样你可以确保 --my-variable-inner
总是在组件中定义,并使外部消费者可以选择定义 --my-variable
.
缺点是你需要记住两个变量名而不是一个。但是在这里你可以想到一些项目范围的约定,例如像那样向每个变量添加 --inner
或其他一些后缀。
我的 Web 组件使用 CSS 个变量。
这些变量需要默认值。
它们在许多文件中使用,所以我想提供默认值一次,而且只提供一次。
第一次尝试使文本变黑。为什么?
一次提供默认值的正确方法是什么?
.a {
--my-variable: red;
}
.b {
--my-variable: var(--my-variable, blue);
}
<div class="a">
<div class="b">
<span style="color: var(--my-variable);">text</span>
</div>
</div>
在 :root
中声明默认值,然后在选择器中覆盖。
:root {
--primary-color: red;
}
* {
color: var(--primary-color);
border: 1px solid var(--primary-color);
padding: 0.25rem;
margin: 0;
}
div {
--primary-color: green;
}
p {
--primary-color: blue;
}
<div>HI!</div>
…
<p>Bye!</p>
This first attempt makes the text black. Why?
因为这个 --my-variable: var(--my-variable, blue);
是无效的,因为你试图用它自己来表达同一个变量,这是不允许的,所以浏览器会简单地忽略它。然后稍后当使用 color: var(--my-variable);
时,颜色将回退到 initial
值,即黑色。
正确的方法是简单地在上层定义变量,它会被所有元素继承(就像@kornieff提供的解决方案)
Custom properties are left almost entirely unevaluated, except that they allow and evaluate the var() function in their value. This can create cyclic dependencies where a custom property uses a var() referring to itself, or two or more custom properties each attempt to refer to each other.
For each element, create a directed dependency graph, containing nodes for each custom property. If the value of a custom property prop contains a var() function referring to the property var (including in the fallback argument of var()), add an edge between prop and the var. Edges are possible from a custom property to itself. If there is a cycle in the dependency graph, all the custom properties in the cycle must compute to their initial value (which is a guaranteed-invalid value).
为了补充前面的答案,在某些情况下您可能不想在全局 :root
范围内声明变量。例如,当您创建一个可重用组件时,您希望在本地声明其样式,而不依赖于全局项目样式。特别是如果您正在为其他开发人员构建库。
在这种情况下,解决方案是将一个变量名暴露给“外部世界”,并在组件内部使用不同的变量名。组件容器应该只是将可选的外部变量映射到内部变量,并设置其默认值:
.my-component-container {
/* map optional "external" variables to required "internal" variables */
--my-variable-inner: var(--my-variable, blue);
}
.my-component-container .my-nested-element {
color: var(--my-variable-inner);
}
.my-component-container .my-other-nested-element {
border-color: var(--my-variable-inner);
}
这样你可以确保 --my-variable-inner
总是在组件中定义,并使外部消费者可以选择定义 --my-variable
.
缺点是你需要记住两个变量名而不是一个。但是在这里你可以想到一些项目范围的约定,例如像那样向每个变量添加 --inner
或其他一些后缀。