suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Benutzerdefinierte CSS-Bereichseigenschaften werden nicht erkannt, wenn sie zum Auswerten von Variablen im übergeordneten Bereich verwendet werden

Ich versuche, die Größe über var benutzerdefinierte Eigenschaften zu skalieren, damit Klassen ohne Kopplung zusammengestellt werden können. Der gewünschte Effekt besteht darin, dass die drei Listen drei verschiedene Maßstäbe haben, aber wie auf CodePen gezeigt, haben alle drei Listen den gleichen Maßstab. Ich suche nach einer Erklärung des Bereichs und der benutzerdefinierten CSS-Eigenschaftstechniken, die dies mit zusammensetzbarem, lose gekoppeltem Code erreichen können.


: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>


P粉006847750P粉006847750392 Tage vor667

Antworte allen(1)Ich werde antworten

  • P粉440453689

    P粉4404536892023-11-02 11:27:45

    在您的情况下,您已在根级别评估了 --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-*


    来自规范

    在第一种情况下,您会陷入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>

    直观上,我们可能认为可以通过更改 :root 级别定义的 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 内求值code> 因此我们已经用它们的值替换了它们。

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

    • 使用 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>

    • :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>

    Antwort
    0
  • StornierenAntwort