用于计算外部作用域中的变量时,CSS作用域定制属性被忽略

用于计算外部作用域中的变量时,CSS作用域定制属性被忽略

我试图通过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>


蝴蝶不菲
浏览 385回答 2
2回答

当年话下

这很棘手,但在您的情况下,您已经--scale在根级别评估了自定义属性以定义--size-*属性,然后您--scale&nbsp;再次定义了内部子元素。这不会再次触发评估,因为它已经在较高级别完成。这是一个简单的例子来说明这个问题:.box&nbsp;{ &nbsp;&nbsp;--color:&nbsp;var(--c,&nbsp;blue);}span&nbsp;{ &nbsp;&nbsp;color:&nbsp;var(--color);}<div> &nbsp;&nbsp;<div&nbsp;class="box"><!--&nbsp;--c&nbsp;is&nbsp;evaluated&nbsp;at&nbsp;this&nbsp;level&nbsp;--> &nbsp;&nbsp;&nbsp;&nbsp;<span&nbsp;style="--c:red">I&nbsp;will&nbsp;not&nbsp;be&nbsp;red&nbsp;because&nbsp;the&nbsp;property&nbsp;is&nbsp;already&nbsp;evaluated&nbsp;and&nbsp;--color&nbsp;is&nbsp;set&nbsp;to&nbsp;blue&nbsp;using&nbsp;the&nbsp;default&nbsp;value</span> &nbsp;&nbsp;</div></div><div&nbsp;style="--c:red"> &nbsp;&nbsp;<div&nbsp;class="box"><!--&nbsp;--c&nbsp;is&nbsp;evaluated&nbsp;at&nbsp;this&nbsp;level&nbsp;--> &nbsp;&nbsp;&nbsp;&nbsp;<span>I&nbsp;will&nbsp;be&nbsp;red&nbsp;because&nbsp;at&nbsp;the&nbsp;time&nbsp;of&nbsp;the&nbsp;evaluation&nbsp;--c&nbsp;is&nbsp;red&nbsp;(inherited&nbsp;from&nbsp;the&nbsp;upper&nbsp;div)</span> &nbsp;&nbsp;</div></div>要解决您的问题,您需要将声明从定义移至:root相同级别--scale:.scale&nbsp;{ &nbsp;&nbsp;--size-1:&nbsp;calc(1&nbsp;*&nbsp;var(--scale,&nbsp;1)&nbsp;*&nbsp;1rem); &nbsp;&nbsp;--size-2:&nbsp;calc(2&nbsp;*&nbsp;var(--scale,&nbsp;1)&nbsp;*&nbsp;1rem); &nbsp;&nbsp;--size-3:&nbsp;calc(3&nbsp;*&nbsp;var(--scale,&nbsp;1)&nbsp;*&nbsp;1rem);}.size-1&nbsp;{&nbsp;font-size:&nbsp;var(--size-1)&nbsp;}.size-2&nbsp;{&nbsp;font-size:&nbsp;var(--size-2)&nbsp;}.size-3&nbsp;{&nbsp;font-size:&nbsp;var(--size-3)&nbsp;}.scale-1x&nbsp;{&nbsp;--scale:&nbsp;1&nbsp;}.scale-2x&nbsp;{&nbsp;--scale:&nbsp;2&nbsp;}.scale-3x&nbsp;{&nbsp;--scale:&nbsp;3&nbsp;}html&nbsp;{ &nbsp;&nbsp;font:&nbsp;1em&nbsp;sans-serif; &nbsp;&nbsp;background:&nbsp;papayawhip;}ol&nbsp;{ &nbsp;&nbsp;float:&nbsp;left; &nbsp;&nbsp;list-style:&nbsp;none; &nbsp;&nbsp;margin:&nbsp;1rem;}<ol&nbsp;class="scale-1x&nbsp;scale"> &nbsp;&nbsp;<li&nbsp;class="size-1">size&nbsp;1</li> &nbsp;&nbsp;<li&nbsp;class="size-2">size&nbsp;2</li> &nbsp;&nbsp;<li&nbsp;class="size-3">size&nbsp;3</li></ol><ol&nbsp;class="scale-2x&nbsp;scale"> &nbsp;&nbsp;<li&nbsp;class="size-1">size&nbsp;1</li> &nbsp;&nbsp;<li&nbsp;class="size-2">size&nbsp;2</li> &nbsp;&nbsp;<li&nbsp;class="size-3">size&nbsp;3</li></ol><ol&nbsp;class="scale-3x&nbsp;scale"> &nbsp;&nbsp;<li&nbsp;class="size-1">size&nbsp;1</li> &nbsp;&nbsp;<li&nbsp;class="size-2">size&nbsp;2</li> &nbsp;&nbsp;<li&nbsp;class="size-3">size&nbsp;3</li></ol>在这种情况下,--scale定义在与其评估相同的级别,因此--size-*将针对每种情况正确定义。从规格:要在属性值中替换var():如果var()函数的第一个参数指定的自定义属性是动画污染的,并且var()函数正在动画属性或其中一个长整数中使用,请将自定义属性视为具有其初始值。其余的这个算法。如果var()函数的第一个参数指定的自定义属性的值不是初始值,则将var()函数替换为相应自定义属性的值。除此以外,如果var()函数的回退值作为其第二个参数,则用回退值替换var()函数。如果后备中有任何var()引用,也可以替换它们。否则,包含var()函数的属性在计算值时间无效在您的第一种情况下,您将落入3,因为--scale在根级别没有指定值。在最后一种情况下,我们将陷入2,因为我们--scale在同一级别定义并且我们有其价值。在所有情况下,我们应该避免任何:root级别的评估,因为它根本没用。根级别是DOM中的最高级别,因此所有元素都将继承相同的值,除非我们再次评估变量,否则不可能在DOM内部具有不同的值。您的代码与此代码相同::root&nbsp;{ &nbsp;&nbsp;--size-1:&nbsp;calc(1&nbsp;*&nbsp;1&nbsp;*&nbsp;1rem); &nbsp;&nbsp;--size-2:&nbsp;calc(2&nbsp;*&nbsp;1&nbsp;*&nbsp;1rem); &nbsp;&nbsp;--size-3:&nbsp;calc(3&nbsp;*&nbsp;1&nbsp;*&nbsp;1rem);}让我们再看一个例子::root&nbsp;{ &nbsp;&nbsp;--r:0; &nbsp;&nbsp;--g:0; &nbsp;&nbsp;--b:255; &nbsp;&nbsp;--color:rgb(var(--r),var(--g),var(--b))}div&nbsp;{ &nbsp;&nbsp;color:var(--color);}p&nbsp;{ &nbsp;&nbsp;--g:100; &nbsp;&nbsp;color:var(--color);}<div> &nbsp;&nbsp;some&nbsp;text</div><p> &nbsp;&nbsp;some&nbsp;text</p>直觉上,我们可能认为我们可以--color通过改变在:root级别定义的3个变量之一来改变它,但我们不能这样做,上面的代码与这个相同::root&nbsp;{ &nbsp;&nbsp;--color:rgb(0,0,255)}div&nbsp;{ &nbsp;&nbsp;color:var(--color);}p&nbsp;{ &nbsp;&nbsp;--g:100; &nbsp;&nbsp;color:var(--color);}<div> &nbsp;&nbsp;some&nbsp;text</div><p> &nbsp;&nbsp;some&nbsp;text</p>该3个变量(--r,--g,--b)进行评估里面:root,所以我们已经与他们的价值观取代他们。在这种情况下,我们有两种可能性:更改:root使用JS或其他CSS规则中的变量。这不允许我们有不同的颜色::root&nbsp;{ &nbsp;&nbsp;--r:0; &nbsp;&nbsp;--g:0; &nbsp;&nbsp;--b:255; &nbsp;&nbsp;--color:rgb(var(--r),var(--g),var(--b))}div&nbsp;{ &nbsp;&nbsp;color:var(--color);}p&nbsp;{ &nbsp;&nbsp;--g:200;&nbsp;/*this&nbsp;will&nbsp;not&nbsp;have&nbsp;any&nbsp;effect&nbsp;!*/ &nbsp;&nbsp;color:var(--color);}:root&nbsp;{ &nbsp;&nbsp;--g:200;&nbsp;/*this&nbsp;will&nbsp;work*/}<div> &nbsp;&nbsp;some&nbsp;text</div><p> &nbsp;&nbsp;some&nbsp;text</p>在所需元素内再次评估变量。在这种情况下,我们将失去任何灵活性,内部的定义:root将变得无用(或至少将成为默认值)::root&nbsp;{ &nbsp;&nbsp;--r:0; &nbsp;&nbsp;--g:0; &nbsp;&nbsp;--b:255; &nbsp;&nbsp;--color:rgb(var(--r),var(--g),var(--b))}div&nbsp;{ &nbsp;&nbsp;color:var(--color);}p&nbsp;{ &nbsp;&nbsp;--g:200; &nbsp;&nbsp;--color:rgb(var(--r),var(--g),var(--b)); &nbsp;&nbsp;color:var(--color);}<div> &nbsp;&nbsp;some&nbsp;text</div><p> &nbsp;&nbsp;some&nbsp;text</p>考虑到这一点,我们应该始终将评估保持在DOM树中的最低点,尤其是在变量发生变化之后(或者在同一级别)这是我们不应该做的:root&nbsp;{ &nbsp;&nbsp;--r:&nbsp;0; &nbsp;&nbsp;--g:&nbsp;0; &nbsp;&nbsp;--b:&nbsp;0;}.color&nbsp;{ &nbsp;&nbsp;--color:&nbsp;rgb(var(--r),&nbsp;var(--g),&nbsp;var(--b))}.green&nbsp;{ &nbsp;&nbsp;--g:&nbsp;255;}.red&nbsp;{ &nbsp;&nbsp;--r:&nbsp;255;}p&nbsp;{ &nbsp;&nbsp;color:&nbsp;var(--color);}h1&nbsp;{ &nbsp;&nbsp;border-bottom:&nbsp;1px&nbsp;solid&nbsp;var(--color);}<div&nbsp;class="color"> &nbsp;&nbsp;<h1&nbsp;class="red">Red&nbsp;</h1> &nbsp;&nbsp;<p&nbsp;class="red">I&nbsp;want&nbsp;to&nbsp;be&nbsp;red&nbsp;:(</p></div><div&nbsp;class="color"> &nbsp;&nbsp;<h1&nbsp;class="green">Green&nbsp;</h1> &nbsp;&nbsp;<p&nbsp;class="green">I&nbsp;want&nbsp;to&nbsp;be&nbsp;green&nbsp;:(</p></div>这是我们应该做的:root&nbsp;{ &nbsp;&nbsp;--r:0; &nbsp;&nbsp;--g:0; &nbsp;&nbsp;--b:0;}.color&nbsp;{ &nbsp;&nbsp;--color:rgb(var(--r),var(--g),var(--b));}.green&nbsp;{ &nbsp;&nbsp;--g:255;}.red&nbsp;{ &nbsp;&nbsp;--r:255;}p&nbsp;{ &nbsp;&nbsp;color:var(--color);}h1&nbsp;{ &nbsp;&nbsp;border-bottom:&nbsp;1px&nbsp;solid&nbsp;var(--color);}<div&nbsp;class="red"> &nbsp;&nbsp;<h1&nbsp;class="color">Red&nbsp;title</h1> &nbsp;&nbsp;<p&nbsp;class="color">Yes&nbsp;I&nbsp;am&nbsp;red&nbsp;:D</p></div><div&nbsp;class="green"> &nbsp;&nbsp;<h1&nbsp;class="color">Green&nbsp;title</h1> &nbsp;&nbsp;<p&nbsp;class="color">Yes&nbsp;I&nbsp;am&nbsp;green&nbsp;:D</p></div>我们也可以这样做::root&nbsp;{ &nbsp;&nbsp;--r:0; &nbsp;&nbsp;--g:0; &nbsp;&nbsp;--b:0;}.color&nbsp;{ &nbsp;&nbsp;--color:rgb(var(--r),var(--g),var(--b));}.green&nbsp;{ &nbsp;&nbsp;--g:255;}.red&nbsp;{ &nbsp;&nbsp;--r:255;}p&nbsp;{ &nbsp;&nbsp;color:var(--color);}h1&nbsp;{ &nbsp;&nbsp;border-bottom:&nbsp;1px&nbsp;solid&nbsp;var(--color);}<div&nbsp;class="red&nbsp;color"> &nbsp;&nbsp;<h1&nbsp;>Red&nbsp;title</h1> &nbsp;&nbsp;<p&nbsp;>Yes&nbsp;I&nbsp;am&nbsp;red&nbsp;:D</p></div><div&nbsp;class="green&nbsp;color"> &nbsp;&nbsp;<h1>Green&nbsp;title</h1> &nbsp;&nbsp;<p&nbsp;>Yes&nbsp;I&nbsp;am&nbsp;green&nbsp;:D</p></div>

叮当猫咪

因为CSS从上到下...假设您使用的是继承,父元素是否可以从其子元素继承?不...这里的逻辑相同,根在评估时看不到--scale属性。因此,如果一个子元素改变了一个属性,我们就不会反过来重新评估所有的父属性,这将创建周期并且它将无法工作&nbsp;
打开App,查看更多内容
随时随地看视频慕课网APP