这是我的 CSS 变量帖子的后半部分,前半部分在这里。
在本文中,我们将研究 var() 的详细信息。还有两个很酷的例子:
var() 访问自定义属性值(CSS 变量)。其语法如下:
var( <custom-property-name>, <fallback-value>? )
第一个参数必须是 CSS 变量:直接值,例如 var(20px),将导致错误,因为 var() 只接受自定义属性名称。
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 */ }
var(--b,fallback_value) Fallbacks:第二个参数充当后备值,当 --b 无效时使用。
var(--c,) 具有空回退的语法: 如果回退值保留为空,则语法保持有效,并且如果 --c 无效,则默认为空值.
多个逗号: 在 var(--d, var(--e), var(--f), var(--g)) 中,第一个逗号之后的所有内容都是被视为后备,因此如果 --d 无效,则 var() 表达式会将 var(--e)、var(--f)、var(--g) 作为后备进行计算,以确定结果。
var() 作为完整的 CSS 令牌: 该函数充当完整的 CSS 令牌,就像 20px 一样。因此,var(--size)var(--unit)不会创建20px并被视为无效。
将initial与CSS变量一起使用:将initial分配给CSS变量意味着它是无效的。要将初始值显示为值,必须将其放置在后备中。
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 变量的一些高级用例:
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 无法自动选中深色模式下的复选框。
如果我们移不动山,我们就修路。解决方法如下:
当系统设置为灯光模式时:当复选框未选中时,对应“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 变量的深入理解对于将来更复杂的样式和设计来说是非常宝贵的。
以上是CSS 变量的惊人细节 - 使用 var() 和很酷的示例的详细内容。更多信息请关注PHP中文网其他相关文章!