更新时间:2022-03-12 16:21:59
在您的情况下,您已经在根级别评估了--scale
自定义属性以定义--size-*
属性,然后定义了--scale
.这不会再次触发评估,因为它已经在上级中完成.
In your case you have evaluated the --scale
custom property at the root level to define the --size-*
properties and then you defined the --scale
again inside child elements. This will not trigger evaluation again because it was already done in an upper level.
这是一个简单的例子来说明问题:
Here is a simple example to illustrate the issue:
.box {
--color: var(--c, blue);
}
span {
color: var(--color);
}
<div>
<div class="box"><!-- --c is evaluated at this level -->
<span style="--c:red">I will not be red because the property is already evaluated and --color is set to blue using the default value</span>
</div>
</div>
<div style="--c:red">
<div class="box"><!-- --c is evaluated at this level -->
<span>I will be red because at the time of the evaluation --c is red (inherited from the upper div)</span>
</div>
</div>
要解决您的问题,您需要将声明从:root
移到与--scale
定义相同的级别:
To fix your issue, you need to move the declaration from :root
to the same level as the --scale
definition:
.scale {
--size-1: calc(1 * var(--scale, 1) * 1rem);
--size-2: calc(2 * var(--scale, 1) * 1rem);
--size-3: calc(3 * var(--scale, 1) * 1rem);
}
.size-1 { font-size: var(--size-1) }
.size-2 { font-size: var(--size-2) }
.size-3 { font-size: var(--size-3) }
.scale-1x { --scale: 1 }
.scale-2x { --scale: 2 }
.scale-3x { --scale: 3 }
html {
font: 1em sans-serif;
background: papayawhip;
}
ol {
float: left;
list-style: none;
margin: 1rem;
}
<ol class="scale-1x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-2x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-3x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
在这种情况下,--scale
的定义与评估的级别相同,因此将为每种情况正确定义--size-*
.
In this case, --scale
is defined at the same level as its evaluation so --size-*
will be defined correctly for each case.
来自规范:
要 用属性值替换var() :
To substitute a var() in a property’s value:
在第一种情况下,您属于 3 ,因为在根级别没有为--scale
指定值.在最后一种情况下,我们属于 2 ,因为我们在相同的级别上定义了--scale
,并且具有它的值.
In your first situation, you are falling into 3 because there is no value specified for --scale
at the root level. In the last case we are falling into 2 because we defined --scale
at the same level and we have its value.
在所有情况下,我们都应避免在:root
级别进行任何评估,因为它根本没有用.根级别是DOM中的***别,因此所有元素都将继承相同的值,并且除非我们再次评估该变量,否则DOM内部不可能有不同的值.
In all the cases, we should avoid any evaluation at :root
level because it's simply useless. The root level is the uppermost level in the DOM so all the elements will inherit the same value and it's impossible to have different values inside the DOM unless we evaluate the variable again.
您的代码与此等效:
:root {
--size-1: calc(1 * 1 * 1rem);
--size-2: calc(2 * 1 * 1rem);
--size-3: calc(3 * 1 * 1rem);
}
再举一个例子:
Let's take another example:
:root {
--r:0;
--g:0;
--b:255;
--color:rgb(var(--r),var(--g),var(--b))
}
div {
color:var(--color);
}
p {
--g:100;
color:var(--color);
}
<div>
some text
</div>
<p>
some text
</p>
直觉上,我们可能认为可以通过更改在:root
级别定义的3个变量之一来更改--color
,但是我们不能这样做,并且上面的代码与此代码相同:
Intuitively, we may think that we can change the --color
by changing one of the 3 variables defined at :root
level but we cannot do this and the above code is the same as this one:
:root {
--color:rgb(0,0,255)
}
div {
color:var(--color);
}
p {
--g:100;
color:var(--color);
}
<div>
some text
</div>
<p>
some text
</p>
在:root
中对3个变量(--r
,--g
,--b
)进行了求值,因此我们已经用它们的值替换了它们.
The 3 variables (--r
, --g
, --b
) are evaluated inside :root
so we have already substituted them with their values.
在这种情况下,我们有两种可能性:
In such a situation we have 2 possibilities:
:root
中的变量.这将不允许我们使用不同的颜色::root
using JS or another CSS rule. This won't allow us to have different colors:
:root {
--r:0;
--g:0;
--b:255;
--color:rgb(var(--r),var(--g),var(--b))
}
div {
color:var(--color);
}
p {
--g:200; /*this will not have any effect !*/
color:var(--color);
}
:root {
--g:200; /*this will work*/
}
<div>
some text
</div>
<p>
some text
</p>
:root
中的定义将变得无用(或至少将成为默认值)::root
will become useless (or at least will become the default value):
:root {
--r:0;
--g:0;
--b:255;
--color:rgb(var(--r),var(--g),var(--b))
}
div {
color:var(--color);
}
p {
--g:200;
--color:rgb(var(--r),var(--g),var(--b));
color:var(--color);
}
<div>
some text
</div>
<p>
some text
</p>
考虑到这一点,我们应该始终将评估保持在DOM树中的最低点,尤其是在变量更改后(或处于同一级别)
Considering this, we should always keep the evaluation at the lowest possible point in the DOM tree and especially after the variable changes (or at the same level)
这是我们不应该做的
:root {
--r: 0;
--g: 0;
--b: 0;
}
.color {
--color: rgb(var(--r), var(--g), var(--b))
}
.green {
--g: 255;
}
.red {
--r: 255;
}
p {
color: var(--color);
}
h1 {
border-bottom: 1px solid var(--color);
}
<div class="color">
<h1 class="red">Red </h1>
<p class="red">I want to be red :(</p>
</div>
<div class="color">
<h1 class="green">Green </h1>
<p class="green">I want to be green :(</p>
</div>
这是我们应该做的
:root {
--r:0;
--g:0;
--b:0;
}
.color {
--color:rgb(var(--r),var(--g),var(--b));
}
.green {
--g:255;
}
.red {
--r:255;
}
p {
color:var(--color);
}
h1 {
border-bottom: 1px solid var(--color);
}
<div class="red">
<h1 class="color">Red title</h1>
<p class="color">Yes I am red :D</p>
</div>
<div class="green">
<h1 class="color">Green title</h1>
<p class="color">Yes I am green :D</p>
</div>
我们也可以这样:
:root {
--r:0;
--g:0;
--b:0;
}
.color {
--color:rgb(var(--r),var(--g),var(--b));
}
.green {
--g:255;
}
.red {
--r:255;
}
p {
color:var(--color);
}
h1 {
border-bottom: 1px solid var(--color);
}
<div class="red color">
<h1 >Red title</h1>
<p >Yes I am red :D</p>
</div>
<div class="green color">
<h1>Green title</h1>
<p >Yes I am green :D</p>
</div>