当前位置 : 主页 > 网页制作 > css >

用于在外部作用域中计算var时忽略CSS作用域自定义属性

来源:互联网 收集:自由互联 发布时间:2021-06-13
我试图通过var自定义属性来扩展大小,这种类可以在没有耦合的情况下组成.期望的效果是3个列表将是3个不同的比例,但是作为 demo’d on codepen,所有3个列表是相同的比例.我正在寻找范围的
我试图通过var自定义属性来扩展大小,这种类可以在没有耦合的情况下组成.期望的效果是3个列表将是3个不同的比例,但是作为 demo’d on 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>
它在某种程度上是棘手的,但在你的情况下,你已经在根级别评估了–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- *将针对每种情况正确定义.

从the specification开始:

To substitute a var() in a property’s value:

  1. If the custom property named by the first argument to the var()
    function is animation-tainted, and the var() function is being used in
    the animation property or one of its longhands, treat the custom
    property as having its initial value for the rest of this algorithm.
  2. If the value of the custom property named by the first argument to the
    var() function is anything but the initial value, replace the var()
    function by the value of the corresponding custom property. Otherwise,
  3. if the var() function has a fallback value as its second argument,
    replace the var() function by the fallback value. If there are any
    var() references in the fallback, substitute them as well.
  4. Otherwise, the property containing the var() function is invalid at
    computed-value time

在你的第一种情况下,你正在落入(3)因为在根级别没有为–scale指定值,但在最后一种情况下我们落入(2)因为我们定义了–scale在同一级别并且我们有它的价值.

在所有情况下,我们应该避免在根级别进行任何评估,因为它根本没用.根级别是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>

直觉上,我们可能认为我们可以通过更改在根级别定义的3个变量中的一个来改变–color但不是.我们不能这样做,上面的代码与此相同:

:root {
  --color:rgb(0,0,255)
}
div {
  color:var(--color);
}
p {
  --g:100;
  color:var(--color);
}
<div>
  some text
</div>
<p>
  some text
</p>

3个变量( – r, – g, – b)在内部进行评估:root所以我们已经可以用它们的值来替换它们.

在这种情况下,我们有2个可能性:

>使用JS或其他CSS规则更改: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>

考虑到这一点,我们应该始终将评估保持在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>
网友评论