我看到最近有很多人对此感到困惑,包括我自己,所以我想把它写下来。
让我们在CSS中加入几个自定义属性:
html {
--color-1: red;
--color-2: blue;
}
让我们马上用它们来做一个背景梯度:
html {
--color-1: red;
--color-2: blue;
--bg: linear-gradient(to right, var(--color-1), var(--color-2));
}
现在说说页面上有几个div:
<div></div>
<div class="variation"></div>
让我把它们变成样式。
div {
background: var(--bg);
}
这完全可行!是的,是的。
现在让我为这个变体设计一下。我不想让它从红色变成蓝色,我想让它从绿色变成蓝色。简单粗暴,我把红色更新为绿色:
html {
--color-1: red;
--color-2: blue;
--bg: linear-gradient(to right, var(--color-1), var(--color-2));
}
div {
background: var(--bg);
}
.variation {
--color-1: green;
}
不!(警报器在响,喇叭在鸣,农场动物在躲避):
朋友们,那是行不通的。
根据我的理解,问题在于:--bg 从未在任何一个 div 上声明。它可以使用 --bg ,因为它被声明得更高,但当它在那里被使用时,它的值已被锁定。仅仅因为你改变了--bg 在声明时恰好使用的其他属性,并不意味着该属性会去寻找它被使用的地方,并更新所有使用它作为依赖的地方。
呃,这个解释感觉不太对。但这是我得到的最好的解释。
解决办法是什么?嗯,有几个。
解决方案1:将变量的范围扩大到你使用它的地方。
你可以这样做:
html {
--color-1: red;
--color-2: blue;
}
div {
--bg: linear-gradient(to right, var(--color-1), var(--color-2));
background: var(--bg);
}
.variant {
--color-1: green;
}
现在,--bg 在两个div上都被声明了,对--color-1 的依赖性的改变确实有效。
解决方案2:用逗号隔开你设置大多数变量的选择器。
假设你做了一件常见的事情,即在:root 。然后你就会遇到这个问题。你可以在那个主声明中添加额外的选择器,以确保你击中正确的范围:
html,
div {
--color-1: red;
--color-2: blue;
--bg: linear-gradient(to right, var(--color-1), var(--color-2));
}
div {
background: var(--bg);
}
.variation {
--color-1: green;
}
在其他一些也许不那么矫揉造作的例子中,它可能看起来是这样的:
:root,
.button,
.whatever-it-is-a-bandaid {
--padding-inline: 1rem;
--padding-block: 1rem;
--padding: var(--padding-block) var(--padding-inline);
}
.button {
padding: var(--padding);
}
.button.less-wide {
--padding-inline: 0.5rem;
}
解决方案3:空白模式
去它的--把变量放在任何地方:
* {
--access: me;
--whereever: you;
--want: to;
--hogwild: var(--access) var(--whereever);
}
这不是一个好计划,我最近无意中听到一个聊天,一个中等规模的网站经历了500ms的页面渲染延迟,因为每次绘制页面都需要计算所有的属性。这是 "有效的",但这是一个罕见的情况,你可以用选择器造成合法的性能问题。
解决方案4:引入一个新的 "默认 "属性和回退机制
所有这些都要归功于Stephen Shaw,他对这一切的探索是我首先看到这种混乱的地方之一。
让我们回到这个问题的第一个示范:
html {
--color-1: red;
--color-2: blue;
--bg: linear-gradient(to right, var(--color-1), var(--color-2));
}
我们要做的是给自己两样东西:
- 一种覆盖整个背景的方法
- 一种覆盖部分渐变背景的方法
所以我们要这样做:
html {
--color-1: red;
--color-2: blue;
}
div {
--bg-default: linear-gradient(to right, var(--color-1), var(--color-2));
background: var(--bg, var(--bg-default));
}
注意,我们根本没有声明--bg 。它只是坐在那里等待一个值,如果它得到了一个值,那就是 "赢"。但如果没有一个值,它将回到我们的--bg-default 。现在...
- 如果我设置
--color-1或--color-2,它就会像预期的那样替换掉那部分梯度(只要我在接触到其中一个 div 的选择器上这么做)。 - 或者,我可以设置
--bg,将整个背景重置为我想要的样子。
感觉这是个不错的处理方式。