css变量问题:父元素的一个变量A的值取决于该元素上定义的的另一个变量B,如果我在其子元素上重新定义一个B,并使用A做为某个属性的值,那么此时A的值是等于父元素上的变量B的值呢?还是重新定义的这个B的值呢?
<div class="container">
<div class="A"></div>
<div class="B"></div>
</div>
.container {
--light-color: red;
--dark-color: green;
--color: var(--light-color);
}
.A, .B {
height: 100px;
}
.A {
background-color: var(--color);
}
.B {
--light-color: blue;
background-color: var(--color);
}
我想为这个组件提供两种风格,浅色和暗色,故定义了两个环境变量
--light-color: red;
--dark-color: green;
但是我想为它的子组件提供不一样的浅色风格,于是重新定义了
--light-color: blue;
最终的颜色却没有向我所想的那样,还是父元素上定义的颜色。当我检查该元素的样式时,发现父元素上的--light-color
变量是被划掉的,应用的应该是子元素上的--light-color,与事实不符,这可能是开发者工具的一个bug吧。
codesandbox
为什么没有改变呢?
猜测:
在.container
元素上的变量有
--light-color: red;
--dark-color: green;
--color: var(--light-color);
--color
在计算的时候只会从当前节点及其祖先节点中找这个--light-color
,所以子元素中的--light-color
它是看不到的。
子元素.B
上的变量有
--light-color
它需要用到--color
,但是自己没有,就去父元素上找。所以还是这里的--light-color
并没有改变.B
的颜色。
之前的想法,认为这样是可行的。是我们在考虑.B
时,将它继承的和自身定义的都集中在一起了,后定义的覆盖掉了前面的,之后再来决定.B
的变量取值,这是我们在思考css时通常的思考方式,但在这里不可行。
不是 BUG ,控制台划掉的只是因为
--light-color
变量被覆盖了,跟--color
变量的值无关,所以--color
还是在.container
中赋值的--light-color
,即red
,你点一下那个高亮还会有辅助指向发生这个问题的核心是:css 变量是基于 重新定义 来实现覆盖的,所以它 没办法改变变量值
内部作用域覆盖,只是 让变量先找内部作用域,而 不是 修改外部已经定义的变量值
因此上述代码可以这样改(省略掉中间变量
color
):css 变量的作用域是可以覆盖,但是如果这个变量的值是另一个变量,在
var
的时候,其实已经是一个字符串了,不是引用了,所以再怎么改.B
的变量,也不会生效,除非你重新定义一遍(当然这样没啥意义,不如去掉)