使用CSS自定义属性使CSS动态

本文概述

  • 原始且功能较弱的CSS变量
  • 完善的CSS变量
  • 防弹CSS自定义属性
  • 使用JavaScript更改自定义属性的值
  • 有趣的用例
  • 将新生命带入你的CSS文件
如果你已经编写CSS已有一段时间了, 那么你必须在某个时候意识到需要变量。 CSS自定义属性有点像CSS自己的变量实现。但是, 如果使用得当, 它们不仅仅可以作为变量。
CSS自定义属性使你可以:
  • 使用你选择的名称为属性分配任意值
  • 使用var()函数在其他属性中使用这些值
尽管目前对CSS自定义属性的支持有些困难, 并且某些浏览器在需要预先激活或将其设置为true的标志下支持它们, 但是预计它们的支持会大大增加, 因此了解这一点很重要如何使用和利用它们。 1个
使用CSS自定义属性使CSS动态

文章图片
在本文中, 你将学习如何使用CSS自定义属性使样式表更具动态性, 也许会使资产管道中多余的Sass / LESS步骤过时。
原始且功能较弱的CSS变量 在我们开始讨论CSS自定义属性之前, 应该指出, 很长一段时间以来, CSS都有一种变量, 即currentColor关键字。这个很少使用但得到广泛支持的变量是指元素的当前颜色值。它可以用于任何接受颜色值的声明, 并且可以完美地级联。
让我们看一个例子:
.element { color: blue; border: 2px solid currentColor; /* Sets a solid, 2px wide, blue border to the element */ }

除级联外, 还可以产生以下内容:
.element span { background: currentColor; /* Sets a blue background color for every span child of .element, unless a color property is declared in this same block */ }.element span.red { color: red; /* Sets a red background color for every span child of .element that has the class .red, since currentColor is applied to the background of every span child of .element no matter if they have the .red class or not */ }

除了它本身不是规范中的变量这一事实之外, currentColor的主要问题在于它仅接受color属性的值, 这在某些情况下可能会使其难以使用。
完善的CSS变量 使用CSS预处理器/后处理器的主要优点之一是, 它们允许将值存储在关键字中, 并在必要时将它们的作用域限定为某个选择器。
在开发人员长期要求后, 编写了解释CSS原生变量的草案。这些正式称为CSS自定义属性, 但有时也称为CSS变量。
当前的本机CSS自定义属性规范涵盖了与前/后处理器变量相同的所有行为。这样一来, 你就可以存储颜色代码, 具有所有已知单位的大小, 或者在需要时仅存储整数(例如, 当你需要使用相同的除数或乘数时)。
与其他语言相比, CSS自定义属性的语法有些奇怪, 但是如果将它们的语法与同一CSS生态系统中的其他功能进行比较, 则很有道理:
:root { --color-black: #2e2e2e; }.element { background: var(--color-black); }

现在, 你可能会想:” 那是一种语法!?”
好吧, 正如Lea Verou在她的精彩演讲CSS变量:var(–subtitle)中所说的那样, 它绝对简单地解释了这种” 破折号” 语法的原因:
它们的工作方式与任何其他CSS属性[…]完全相同。许多人问我为什么我们不使用美元符号, 而我们不使用美元符号的原因是我们希望人们能够同时使用SASS或预处理器变量, CSS变量。它们都是不同的东西, 它们实现不同的目标, 有些事情可以用CSS变量来完成, 而SASS绝对不能做到, 有些事情可以用SASS变量来解决, 而CSS变量则不能, 所以我们想要人们可以在同一个样式表中使用它们, 因此你可以将破折??号语法想象为带有空前缀的prefix属性。
我们可以使用var()函数检索自定义属性的值, 该函数可以在除选择器, 属性名称或媒体查询声明之外的所有地方使用。
值得注意的是, 虽然前/后处理器变量仅在编译时使用, 但CSS变量可以动态使用和更新。这是什么意思?这意味着它们保留在实际的CSS样式表中。因此, 即使在样式表编译后, 它们仍然是变量的概念仍然存在。
为了更加清楚, 让我使用一些示例来说明这种情况。以下代码块是SASS样式表的一部分:
:root { $value: 30px; }@media screen and (min-width: 768px) { $value: 60px; }.corners { border-radius: $value; }

【使用CSS自定义属性使CSS动态】SASS声明和规则的此片段按以下方式编译为CSS:
.corners { border-radius: 30px; }

你会看到:root内的属性和媒体查询在编译后都会丢失, 因为SASS变量不能存在于CSS文件中(或者更确切地说, 可以强制它们存在于CSS文件中, 但是会被忽略)由于它们的某些语法是无效的CSS), 因此该变量的值之后将无法更新。
现在, 我们考虑相同的情况, 但仅使用CSS变量(未应用CSS前置/后处理器)(即, 不执行任何转译或编译)来应用:
:root { --value: 30px; }@media screen and (min-width: 768px) { --value: 60px; }.corners { border-radius: var(--value); }

显然, 由于我们没有进行任何编译/转译, 因此没有任何变化, 并且custom属性的值可以动态更新。因此, 例如, 如果我们使用JavaScript之类的方法来更改– value的值, 则该值将在使用var()函数调用的每个实例中更新。
自定义属性的功能使此功能如此强大, 你甚至可以执行自动前缀之类的操作。
Lea Verou使用clip-path属性设置了一个示例。首先, 将要添加前缀的属性的值设置为initial, 但使用自定义属性, 然后将每个带前缀的属性的值设置为自定义属性值:
* { --clip-path: initial; -webkit-clip-path: var(--clip-path); clip-path: var(--clip-path); }

之后, 剩下的就是更改选择器中的custom属性的值:
header { --clip-path: polygon(0% 0%, 100% 0%, 100% calc(100% - 2.5em), 0% 100%); }

如果你想进一步了解这一点, 请查看Lea关于使用CSS变量自动前缀的完整文章。
防弹CSS自定义属性 如前所述, 浏览器对CSS自定义属性的支持在很大程度上仍是非标准的。那么如何克服呢?
这就是PostCSS及其插件postcss-css-variables发挥作用的地方。
如果你想知道PostCSS是什么, 请查看我的文章PostCSS:SASS的新播放日期, 并在完成后返回此内容。然后, 你将基本了解如何使用此出色的工具进行操作, 并且在阅读本文的其余部分时不会迷失方向。
使用postcss-css-variables插件, 并将其keep选项设置为true时, 我们可以将所有var()函数声明保留在输出中, 并将计算出的值作为后备声明。它还保留计算的– var声明。请记住, 使用此PostCSS插件, 自定义属性可以在转译过程后动态更新, 但是后备值将保持不变, 除非它们专门针对目标并且明确地进行了单独更改。
如果你正在寻找不使用前/后处理器的CSS变量使用方法, 则始终可以使用CSS @support规则手动检查当前支持, 并在支持不完整或不存在支持时应用适当的备用。例如:
:root { --color-blue: #1e90ff; /* hex value for dodgerblue color */ }.element { background: var(--color-blue); }@supports (not(--value: 0)) { /* CSS variables not supported */ .element { background: dodgerblue; } }

使用JavaScript更改自定义属性的值 我在整篇文章中都提到可以使用JavaScript更新变量, 所以让我们开始吧。
假设你有一些如下所示的CSS, 假设你有一个浅色主题, 并且想要将其切换为深色主题:
:root { --text-color: black; --background-color: white; }body { color: var(--text-color); background: var(--background-color); }

你可以通过执行以下操作来更新– text-color和– background-color自定义属性:
var bodyStyles = document.body.style; bodyStyles.setProperty('--text-color', 'white'); bodyStyles.setProperty('--background-color', 'black');

有趣的用例 经过多年的开发和关于CSS自定义属性规范的讨论, 出现了一些有趣的用例。这里有一些例子:
主题:在实现CSS变量时, 为网站使用一组主题非常容易。想要你当前样式的浅色或深色变化?只需使用JavaScript更改某些自定义属性的值, 即可完成。
间距调整:是否需要微调站点的间距, 例如列之间的排水沟?更改单个CSS变量的值, 并在站点范围内看到此更改。
完全动态的calc()函数:现在, 你可以在这些函数中使用自定义属性来拥有完全动态的calc()函数, 无需在JavaScript中进行复杂的或短暂的计算, 然后在每个实例上手动更新这些值。
将新生命带入你的CSS文件 CSS定制属性是一种功能强大且创新的方法, 可为样式表赋予更多生命, 并首次在CSS中引入完全动态的值。
该规范目前处于候选推荐标准状态, 这意味着标准化指日可待, 这是深入了解此功能并从中获得最大收益的充分理由。
  1. 注意:正如Lea Verou在4月22日指出的那样, 几乎所有主流浏览器默认都支持自定义属性, 而无需切换标志。除非需要支持旧版本的浏览器, 否则将其用于生产是安全的。 ?

    推荐阅读