【问题标题】:CSS Variables inheritance and fallbackCSS 变量继承和回退
【发布时间】:2018-06-13 06:07:47
【问题描述】:

我的问题是为什么 CSS 变量需要添加回退的概念,而不是像其他 CSS 属性那样仅仅依赖于继承。

例如:

:root {
 --color1: red;
}

body {
 color: var(--color1);
}

body p {
 color: var(--color2);
 --color2: blue;
}

body span {
  --color3: green;
  color: var(--color3);
  color: yellow;
  color: var(--color4);
}
<body>
  Text 1
  <p>
    Text 2
  </p>
  <span>
    Text 3
  </span>
</body>

文本 3 最终变为红色而不是绿色或黄色。虽然关卡上有有效的属性,但它采用父颜色值,而不是验证同一关卡上是否有其他有效值。当变量名无效时会发生这种情况。

显然 CSS 变量有一个特殊的回退,所以你需要使用类似的东西:

color: var(--color4, yellow);

但这意味着再次重复颜色,因为

color: var(--color4, --color3);

不起作用。两者都不是:

color: var(--color3, yellow, blue);

或任何其他多个值。

也不支持 inheritcurrentColorinitial 等关键字。所以我不确定如何依赖继承,因为显然我需要对给定的值非常明确。在 Firefox 57.0.1 和 Chrome 63 上测试。

我知道 CSS variables 仍然是 Working Draft 所以也许这就是当前行为的原因。

【问题讨论】:

    标签: css inheritance css-variables


    【解决方案1】:

    正如 JoseAPL 所说,var() 表达式接受回退参数而不是默认继承的原因仅仅是因为虽然自定义属性 确实 继承,但并非所有您将使用它们的标准属性做。

    另一方面,如果你问为什么 var() 表达式不默认为下一个最佳级联值,那是因为在评估 var() 表达式时,没有其他值回退到,因为级联中的所有其他声明都已被删除。请参阅第 3.1 节,其中定义了术语 invalid at computed-value time

    注意:存在计算值时无效的概念是因为变量不能像其他语法错误那样“提前失败”,所以当用户代理意识到属性值无效时,它已经被丢弃了另一个级联价值观。

    话虽如此,您可以提供一个自定义属性作为后备值(只要它是 not the same one,原因与上述相同)——该自定义属性只需要出现在它的拥有var() 表达式,因为备用值是一个声明,而不是属性名称。

    所以结果是一个 var() 嵌套在另一个 var() 中:

    body span {
      --color3: green;
      color: var(--color3);
      color: yellow;
      color: var(--color4, var(--color3));
    }
    

    :root {
     --color1: red;
    }
    
    body {
     color: var(--color1);
    }
    
    body p {
     color: var(--color2);
     --color2: blue;
    }
    
    body span {
      --color3: green;
      color: var(--color3);
      color: yellow;
      color: var(--color4, var(--color3));
    }
    <body>
      Text 1
      <p>
        Text 2
      </p>
      <span>
        Text 3
      </span>
    </body>

    【讨论】:

    • 感谢您的回答。我将尝试阅读有关“计算价值时间”和“使用价值时间”的更多信息,以阐明级联值。还要感谢您声明您需要嵌套 var() 定义。
    • 再一次,我希望回退没有限制,因为我不知道其他值被限制为 2。例如 font-family 没有这个限制。
    • @Ecaterina Moraru:自定义属性的语法与 font-family 非常不同。事实上,这正是允许某人做this 之类的事情的原因。
    • 我的问题来自color: var(--color3, yellow, blue); 无效,而font-family: var(--font-body, Verdana, sans-serif); 有效。因此,您需要了解您赋予价值的属性及其期望:值、列表。它可以自动截断字符串,但我想这样更安全。谢谢你的回答。
    【解决方案2】:

    首先

    并非 CSS 中的所有属性都是继承的,请参阅这些链接,以便了解继承了哪些 CSS 属性以及如何应用继承:

    https://www.w3.org/TR/CSS22/propidx.html
    https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance


    第二

    声明重复属性的顺序很重要。

    如果你要应用的颜色是green这不一样:

    // correct way to declare fallback color, it will be green and yellow if --color3 was not defined
    body span {
      --color3: green;
      color: yellow;
      color: var(--color3);
    }
    

    作为:

    body span { // incorrect way to declare fallback color
      --color3: green;
      color: var(--color3);
      color: yellow;
      color: var(--color4);
    }
    

    将采用属性 color: var(--color4);,因为此声明中没有无效语法,但由于没有声明为 --color4 的变量,因此将应用继承的颜色(在这种情况下来自 body { color: var(--color1) } em>)

    因为coloris a inherited property


    第三

    使用var() 的后备是另一种解决方案,但前一个是不支持var() 的旧浏览器的后备

    另外,你用错了,使用var()的fallback的正确方法应该是这样的:

    color: var(--color4, var(--color3));
    

    或者这个:

    color: var(--color4, var(--color3, yellow));
    

    var() 仅接受 2 个参数,即您要使用的值和备用值。
    使用语法见following link


    结论

    由于var() 并非在所有浏览器中都可用,所以我会选择正确的方式使用重复的属性,或者你可以同时使用它们。

    :root {
     --color1: red;
    }
    
    body {
     color: var(--color1);
    }
    
    body p {
     color: var(--color2);
     --color2: blue;
    }
    
    body span {
      --color3: green;
      color: yellow;
      color: var(--color4, var(--color3));
    }
    <body>
      Text 1
      <p>
        Text 2
      </p>
      <span>
        Text 3
      </span>
    </body>

    【讨论】:

    • 这个答案没有试图解决 why var() 旨在使用回退而不是默认情况下依赖继承(尽管并非所有属性都被继承的事实是一个似是而非的解释,如果不是很明显的话)。
    • @BoltClock 我应该在第一个问题上走得更远,但我也试图澄清这个问题有错误,可能会对var 的概念造成误解,我应该更新我的答案吗?
    • “第三”部分也不正确。当自定义属性不可用时,使用 var() 中的回退。这不是旧浏览器的解决方案 - 他们无论如何都不会看到它,因为他们不理解 var() 本身的含义。
    • 我认为提问者理解 var() 的工作原理,事实上他们已经精心设计了他们的 CSS 来证明他们的观点。所以没有什么需要澄清的。
    猜你喜欢
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 2014-04-06
    • 2013-02-11
    相关资源
    最近更新 更多