我试图通过var自定义属性进行缩放,使类可以在不耦合的情况下进行组合。所期望的效果是,这3个列表将在3个不同的规模,但作为在CodePen上演示,所有3个列表是相同的规模。我正在寻找关于作用域和CSS自定义属性技术的解释,它可以通过可组合的松散耦合代码来实现这一点。
:root {
--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">
<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">
<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">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
发布于 2018-08-25 09:24:16
在您的示例中,您已经在根级别评估了--scale自定义属性以定义--size-*属性,然后在子元素中再次定义--scale。这不会再次触发评估,因为它已经在高级中完成了。
下面是一个简单的例子来说明这个问题:
.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定义相同的级别:
.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-*。
来自规格
若要替换属性值中的var(),请执行以下操作:
在第一种情况下,您将陷入3,因为在根级没有为--scale指定值。在最后一个例子中,我们进入了2,因为我们在相同的级别上定义了--scale,并且我们有它的值。
在所有情况下,我们都应该避免在:root级别上进行任何评估,因为它根本没用。根级别是DOM中的最上层,所以所有元素都将继承相同的值,除非我们再次计算变量,否则在DOM中不可能有不同的值。
您的代码与此代码等效:
:root {
--size-1: calc(1 * 1 * 1rem);
--size-2: calc(2 * 1 * 1rem);
--size-3: calc(3 * 1 * 1rem);
}让我们再举一个例子:
: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>
从直觉上讲,我们可能认为可以通过更改在--color级别上定义的三个变量中的一个来更改:root,但我们不能这样做,而且上面的代码与这个相同:
:root {
--color:rgb(0,0,255)
}
div {
color:var(--color);
}
p {
--g:100;
color:var(--color);
}<div>
some text
</div>
<p>
some text
</p>
三个变量(--r、--g、--b)在:root中进行计算,因此我们已经用它们的值替换了它们。
在这种情况下,我们有三种可能性:
:root中的变量。这将不允许我们有不同的颜色:
: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 {
--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>
:root *更改*选择器。这将确保在所有级别上定义和评估我们的函数。在某些复杂的情况下,这可能会产生一些不必要的结果。
* {
--r:0;
--g:0;
--b:255;
--color:rgb(var(--r),var(--g),var(--b))
}
div {
color:var(--color);
}
p {
--g:200;
color:var(--color);
}<div>
some text
</div>
<p>
some text
</p>
考虑到这一点,我们应该始终将求值保持在DOM树中的最低可能点,特别是在变量更改后(或在同一级别)。
以下是我们不该做的事
: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>
https://stackoverflow.com/questions/52015737
复制相似问题