首页 >web前端 >css教程 >CSS 变量的惊人细节 - 使用 var() 和很酷的示例

CSS 变量的惊人细节 - 使用 var() 和很酷的示例

Barbara Streisand
Barbara Streisand原创
2024-11-15 05:49:02605浏览

这是我的 CSS 变量帖子的后半部分,前半部分在这里。
在本文中,我们将研究 var() 的详细信息。还有两个很酷的例子:

  • 使用 CSS 变量的动画
  • 带有系统设置检测功能的纯 CSS 深色模式切换

The Surprising Details of CSS Variables - Using var() and Cool Examples

使用 var()

var() 访问自定义属性值(CSS 变量)。其语法如下:

var( <custom-property-name>, <fallback-value>? )

基本规则

  1. 第一个参数必须是 CSS 变量:直接值,例如 var(20px),将导致错误,因为 var() 只接受自定义属性名称。

  2. var() 无法替换属性名称: 换句话说,你不能写类似 var(--prop-name): 20px; 的内容。因为 var() 仅限于在属性值中使用。

.foo {
  margin: var(20px); /* Error, 20px is not a CSS variable */

  --prop-name: margin-top;
  var(--prop-name): 20px; /* Error, cannot use var() this way */
}

详细行为

  1. var(--b,fallback_value) Fallbacks:第二个参数充当后备值,当 --b 无效时使用。

  2. var(--c,) 具有空回退的语法: 如果回退值保留为空,则语法保持有效,并且如果 --c 无效,则默认为空值.

  3. 多个逗号: 在 var(--d, var(--e), var(--f), var(--g)) 中,第一个逗号之后的所有内容都是被视为后备,因此如果 --d 无效,则 var() 表达式会将 var(--e)、var(--f)、var(--g) 作为后备进行计算,以确定结果。

  4. var() 作为完整的 CSS 令牌: 该函数充当完整的 CSS 令牌,就像 20px 一样。因此,var(--size)var(--unit)不会创建20px并被视为无效。

  5. 将initial与CSS变量一起使用:将initial分配给CSS变量意味着它是无效的。要将初始值显示为值,必须将其放置在后备中。

  6. url() 和 var() 用法: 由于 url() 被视为完整的 CSS 令牌,因此您需要在变量中定义完整的 url()。

:root {
  /* 1. */
  margin: var(--b, 20px); /* Uses 20px if --b is invalid */

  /* 2. */
  padding: var(--c,) 20px; /* Falls back to 20px if --c is invalid */

  /* 3. */
  font-family: var(--fonts, "lucida grande", tahoma, Arial); /* Uses fallback font stack if --fonts is invalid */

  /* 4. */
  --text-size: 12;
  --text-unit: px;
  font-size: var(--text-size)var(--text-unit); /* Invalid, as it does not resolve to 12px */

  /* 5. */
  --initialized: initial;
  background: var(--initialized, initial); /* Results in background: initial */

  /* 6. */
  --invalid-url: "https://useme.medium.com";
  background: url(var(--invalid-url)); /* Invalid, as url() cannot parse var() */

  --valid-url: url(https://useme.medium.com);
  background: var(--valid-url); /* Correct usage */
}

可变分辨率和范围

CSS 变量与其他 CSS 属性一样,遵循 CSS 特定的范围和特异性规则。了解这些因素如何影响 CSS 变量可以进行更精确的控制。

全局变量和作用域变量:
:root 中定义的变量是全局应用的,而选择器中定义的变量则具有更有限的范围。

   :root {
     --main-color: blue; /* Globally applied */
   }

   .container {
     --main-color: green; /* Scoped, applies only within .container */
   }

具体优先级:
CSS 变量的较高特异性将覆盖较低特异性。

var( <custom-property-name>, <fallback-value>? )
.foo {
  margin: var(20px); /* Error, 20px is not a CSS variable */

  --prop-name: margin-top;
  var(--prop-name): 20px; /* Error, cannot use var() this way */
}

在此示例中,.box 的背景颜色保持白色,因为在重新定义 .box 之前 --background 已解析为 rgb(255, 255, 255) --green: 0。

使用伪类重新评估变量:
当在同一级别定义时,变量会根据伪类状态而变化。

:root {
  /* 1. */
  margin: var(--b, 20px); /* Uses 20px if --b is invalid */

  /* 2. */
  padding: var(--c,) 20px; /* Falls back to 20px if --c is invalid */

  /* 3. */
  font-family: var(--fonts, "lucida grande", tahoma, Arial); /* Uses fallback font stack if --fonts is invalid */

  /* 4. */
  --text-size: 12;
  --text-unit: px;
  font-size: var(--text-size)var(--text-unit); /* Invalid, as it does not resolve to 12px */

  /* 5. */
  --initialized: initial;
  background: var(--initialized, initial); /* Results in background: initial */

  /* 6. */
  --invalid-url: "https://useme.medium.com";
  background: url(var(--invalid-url)); /* Invalid, as url() cannot parse var() */

  --valid-url: url(https://useme.medium.com);
  background: var(--valid-url); /* Correct usage */
}

接下来,让我们探索 CSS 变量的一些高级用例:

用法示例 A:动画

CSS 变量不能直接动画,因为浏览器无法推断数据类型。要解决此问题,请使用 @property 定义变量的类型和初始值,使浏览器能够了解如何为变量设置动画。

   :root {
     --main-color: blue; /* Globally applied */
   }

   .container {
     --main-color: green; /* Scoped, applies only within .container */
   }
   :root {
     --main-color: blue;
   }

   .section {
     --main-color: green; /* Overrides :root definition */
   }

   .section p {
     color: var(--main-color); /* Shows green */
   }

   p {
     color: var(--main-color); /* Shows blue */
   }

添加与系统偏好设置一致的手动切换

虽然系统设置默认控制主题,但我们可能希望为用户提供手动在浅色和深色主题之间切换的选项。为此,我们可以添加一个复选框来切换状态。理想情况下,当选中该复选框时,它表示深色模式,当取消选中时,它表示浅色模式。

但是,CSS 无法自动检测系统设置并相应地更改复选框状态,尤其是在深色模式下。为了解决这个限制,我们可以使用 CSS 变量和 :has() 选择器来根据复选框状态控制主题切换。

我想尝试完全使用 CSS 来实现此目的,但由于用户的系统可能设置为浅色或深色模式,因此仅靠 CSS 无法自动选中深色模式下的复选框。

如果我们移不动山,我们就修路。解决方法如下:

  • 我们将使用 CSS 创建一个切换开关,其中视觉“OFF”状态代表浅色模式,“ON”代表深色模式。

The Surprising Details of CSS Variables - Using var() and Cool Examples
The Surprising Details of CSS Variables - Using var() and Cool Examples

  • 当系统设置为灯光模式时:当复选框未选中时,对应“OFF”状态(灯光模式)。选择后,对应“ON”状态(深色模式)。

  • 当系统设置为深色模式时:由于系统偏好反转,视觉状态也会反转。当取消选中该复选框时,它对应于“ON”(深色模式)。选择后,对应“OFF”(灯光模式)。

要实现这个效果,我们需要两个主要元素:

第一:根据系统设置和复选框状态更改的变量

var( <custom-property-name>, <fallback-value>? )

第二:根据选中状态和开/关表示的系统设置切换行为

浅色和深色模式 CSS 属性会根据系统设置而颠倒。

.foo {
  margin: var(20px); /* Error, 20px is not a CSS variable */

  --prop-name: margin-top;
  var(--prop-name): 20px; /* Error, cannot use var() this way */
}

使用 CSS 变量技巧简化变量设置

这里我们将使用 Space Toggle 技术来简化变量设置。这是代码,后面是其工作原理的解释:

:root {
  /* 1. */
  margin: var(--b, 20px); /* Uses 20px if --b is invalid */

  /* 2. */
  padding: var(--c,) 20px; /* Falls back to 20px if --c is invalid */

  /* 3. */
  font-family: var(--fonts, "lucida grande", tahoma, Arial); /* Uses fallback font stack if --fonts is invalid */

  /* 4. */
  --text-size: 12;
  --text-unit: px;
  font-size: var(--text-size)var(--text-unit); /* Invalid, as it does not resolve to 12px */

  /* 5. */
  --initialized: initial;
  background: var(--initialized, initial); /* Results in background: initial */

  /* 6. */
  --invalid-url: "https://useme.medium.com";
  background: url(var(--invalid-url)); /* Invalid, as url() cannot parse var() */

  --valid-url: url(https://useme.medium.com);
  background: var(--valid-url); /* Correct usage */
}

这里的关键在于 --background-color: var(--light, #fbfbfb) var(--dark, #121212); 行。这里,背景颜色取决于 --light 和 --dark 的值,有效地模拟属性中的 if/else。

它是如何工作的?最初,--light: var(--ON);和--ON:初始;使 --ON 成为无效状态。同时,--OFF 设​​置为空字符串。当应用于 var(--light, #fbfbfb) var(--dark, #121212) 时,无效的 --light 变量将默认为 #fbfbfb,有效的 --dark 变量(空)允许 --background-color等于#fbfbfb。

所有其他颜色变量都遵循相同的逻辑,根据 --light 和 --dark 的状态进行调整。这样,每个颜色变量只需要定义一次。

切换状态变得简单。如果深色模式处于活动状态,请使用 --light: var(--OFF);和 --dark: var(--ON);。在灯光模式下,反转它们。虽然不是很直观,但这种方法目前对于 CSS 来说是最有效的。如果有更好的解决方案,值得探索。

完整示例:CodePen 示例


概括

CSS 不断发展,自 2016 年以来 CSS 变量在主要浏览器中可用。@property 和 :has() 等新功能进一步扩展了 CSS 变量的灵活性。与其他新工具相结合,CSS 变量变得更加强大 - 例如,它们现在可以增强滚动驱动的动画以创建视觉动态效果。作为 CSS 中存储状态的核心元素,就像任何编程语言中的变量一样,对 CSS 变量的深入理解对于将来更复杂的样式和设计来说是非​​常宝贵的。


参考

  • https://stackoverflow.com/questions/42330075/is-there-a-way-to-interpolate-css-variables-with-url/42331003#42331003
  • https://kizu.dev/circular-toggles/#was-this-always-possible
  • https://dev.to/afif/what-no-one-told-you-about-css-variables-553o
  • https://hackernoon.com/cool-css-variable-tricks-to-try-uyu35e9
  • https://lea.verou.me/blog/2020/10/the-var-space-hack-to-toggle-multiple-values-with-one-custom-property/

以上是CSS 变量的惊人细节 - 使用 var() 和很酷的示例的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn