【问题标题】:how to reset a CSS variable (aka custom properties) and use the fallback one?如何重置 CSS 变量(又名自定义属性)并使用后备变量?
【发布时间】:2019-09-01 01:50:01
【问题描述】:

我正在尝试为盒子模型属性设置 CSS 变量。我想支持为所有方面以及个别方面设置值。我想拥有默认值,但无论哪种方式都可以覆盖。 我尝试使用后备值,但收效甚微。

类似:

:root {
  --border-width-top: 0;
  --border-width-right: 0;
  --border-width-bottom: 0;
  --border-width-left: 0;
  --border-width: 0;
}
div {
  border-color: red;
  border-style: solid;
  border-width: var(--border-width, var(--border-width-top) var(--border-width-right) var(--border-width-bottom) var(--border-width-left));
}


div {
  --border-width-top: 10px;
}

这不会像border-width 有一个默认值一样工作,那么它将始终优先于备用值。 不确定目前是否有办法做到这一点,但我感觉离找到解决方案很近了。

这是我正在玩的堆栈闪电战:stackblitz

【问题讨论】:

  • Kukkuz 的回答适用于您的特定示例,但恐怕您真的在问是否有一种方法可以“取消定义”在 DOM 树中较高层定义的变量。还是我想多了?
  • @MrLister 你是对的,看看 Temani 的解决方案

标签: css css-variables


【解决方案1】:

您可以使用initial 取消设置值以使用备用值:

:root {
  --border-width-top: 2px;
  --border-width-right: 2px;
  --border-width-bottom: 2px;
  --border-width-left: 2px;
  --border-width: 0;
}
div {
  margin:5px;
  border-color: red;
  border-style: solid;
  border-width: var(--border-width, var(--border-width-top) var(--border-width-right) var(--border-width-bottom) var(--border-width-left));
}


div.box {
  --border-width:initial;
  --border-width-top: 10px;
}
<div>some content</div>
<div class="box">some content</div>

来自the specification

自定义属性的初始值是空值;也就是说,什么都没有。此初始值与 var() 表示法有特殊的交互作用,这在定义 var() 的部分中进行了说明。

用 var() 替换属性值:

  1. 如果自定义属性由 var() 的第一个参数命名 函数被动画污染,并且 var() 函数被用于 动画属性或其长手之一,对待自定义 属性具有该算法其余部分的初始值。
  2. 如果自定义属性的值由第一个参数命名为 var() 函数是除了初始值之外的任何东西,替换 var() 通过相应自定义属性的值起作用。否则,
  3. 如果 var() 函数有一个备用值作为它的第二个参数, 用备用值替换 var() 函数。如果有的话 var() 后备中的引用,也替换它们。
  4. 否则,包含 var() 函数的属性在 计算值时间

【讨论】:

  • 太酷了...我发现它有点晚了:)
  • 不错。我不知道初始。您的示例使用法有点复杂,因为我必须确保将 --border-width 定义为初始值,否则将忽略边值。但是我尝试将其设置为根目录中的默认值,它似乎完全符合我的需要。走这条路我可能会错过什么吗?
  • @masimplo 不,是一样的。在根内部或元素内设置初始值将完全相同,因为在评估时它将是初始值,因此我们不在乎 在哪里您设置了初始值。在进行评估时,我们只关心 VAR 的值。
【解决方案2】:

fallback 值仅在变量 --border-width 未定义时有效:

自定义属性的后备值,用于自定义 属性在使用的上下文中无效。

MDN

请看下面的演示:

:root {
  --border-width-top: 0;
  --border-width-right: 0;
  --border-width-bottom: 0;
  --border-width-left: 0;
  /*--border-width: 0;*/
}

div {
  border-color: red;
  border-style: solid;
  border-width: var(--border-width, var(--border-width-top) var(--border-width-right) var(--border-width-bottom) var(--border-width-left));
}

div {
  --border-width-top: 10px;
}
<div id="app">
  <h1>TypeScript Starter</h1>
</div>

【讨论】:

  • 是的,这也是我的理解。我正在寻找一种方法来定义变量,但不为其赋值。这样它就会出现在文档中,但除非明确设置,否则不会影响边界。感谢您的回答。
【解决方案3】:

正如@Temani 解释的那样,您可以使用--varName: initial 为变量设置实际上是空但无效的值。然后将使用var(....)中的any fallback values declared

所以如果你定义--text_color: initial 然后使用选择器:color: var(--text_color, hotpink) 您的文字将是粉红色而不是黑色(如果您直接写 color: initial 就会是这样)。


然后我想知道是否可以使用unset 代替initial。使用--text_color: unset 取消定义变量似乎更自然。它更直观,因为您可能很少使用unset,所以您会记住您的意图。

然而事实证明unsetinitial 的工作方式并不完全相同,但如果您需要继承更高层声明的变量,它有时会很有用。

--text_color: initial

  • 将变量的值设置为空值(请参阅 Tamani 回答中的参考规范)
  • 任何设置--text_color 的祖先节点都将被此声明覆盖
  • 我喜欢这样想,好像你可以设置--text_color: null

--text_color: unset

  • 有效地从该 DOM 节点中完全删除变量。它不会将其设置为神奇的空值 - 它的行为方式与您刚刚从代码中完全删除它一样。
  • 这允许使用任何继承的值。
  • 我喜欢这样想,好像你可以设置--text_color: undefined
  • 因此,如果任何祖先 DOM 节点定义了 --text_color: green 并且您的节点声明了 --text_color: unsetcolor: var(--text_color, blue),它将是绿色而不是蓝色。

这对我很有用,因为我动态设置了很多变量,需要像从未设置过一样取消设置。

这是否是我不能保证的实际规范行为:-)

【讨论】:

    【解决方案4】:

    您也可以在 Javascript 中执行此操作:

    element.style.setProperty('--button_icon_active_color', '')
    element.style.setProperty('--button_icon_active_color', null)
    

    这些都会“取消设置”该值,就好像它从未存在过一样。

    如果您在浏览器控制台中运行此命令,您会看到它从样式中消失。

    【讨论】:

      猜你喜欢
      • 2016-07-05
      • 2019-04-13
      • 2021-07-13
      • 2019-07-02
      • 2021-03-02
      • 1970-01-01
      相关资源
      最近更新 更多