CSS 自定义属性切换技巧

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您的旅程各个阶段提供云产品。从 200 美元的免费额度开始!

早在 2020 年 7 月,我收到一封来自 James0x57(我总是试图用他们的名字称呼人,但我认为我感觉他们更喜欢用屏幕名字)的电子邮件,上面写着

自定义 CSS 属性的分支条件逻辑和批量功能切换的整个世界都是可能的,并且只存在于 CSS 规范中一个被忽视的小脚注。

那一行

注意:虽然 <declaration-value> 必须至少表示一个标记,但该标记可以是空白符。

换句话说,--foo: ; 是有效的。

如果你和我一样,这听起来并不像什么重大的发现,它打开了巨大的大门,但对像 James0x57 这样的聪明人来说,它确实如此!我们开始着手撰写一篇博客文章草稿,但由于种种原因,它最终没有在这里发表。其中一个原因是我根本没明白。叫我笨吧,对不起,James0x57。不过,他们在我要求一个非常简化的例子时给我发送的一个演示很有用,我认为我有点明白了。这是我的解释

让我试着解释一下

  • 我们在这里设置的断点是一个 900px 的 max-width 媒体查询。你可以看到,变量 --mq-sminitial 切换到一个空值的地方就是断点。
  • 当浏览器窗口宽度大于 900px 时,--mq-sm 的值为 initial
    • 这使得变量 --padding-when-small 包含两个值——initial2rem——我想这是无效的
    • 因此,当我们真正设置内边距并调用该变量(例如 padding: var(--padding-when-small, var(--padding-when-large)))时,会使用第二个值(“回退”值),因为第一个值无效。
  • 当浏览器窗口宽度小于 900px 时,--mq-sm 的值为一个空格。
    • 这使得变量 --padding-when-small 的值为 "(空格)2rem",我想这是有效的
    • 这意味着,当我们真正设置内边距并调用该变量(例如 padding: var(--padding-when-small, var(--padding-when-large)))时,会使用第一个值。

因此,现在我们可以通过更改一个占位符变量来在两个值之间切换内边距。

我明白了。

当我看到这仅仅是更改一个单一值时,这几乎就像呃,好吧,你找到了一种非常复杂的方法来更改一些内边距,但你本可以在媒体查询中直接更改内边距。但技巧在于现在我们有了这个已更改的占位符变量,我们可以利用它来更改无限数量的其他值

我们可以在 CSS 中使用单个媒体查询(或一组媒体查询)来切换这些占位符变量,然后我们在其他地方使用它们来切换值。与在整个 CSS 中散布媒体查询相比,这样可能会更好、更简洁。这是一种在 CSS 中进行真正的切换,就像一种我们以前从未有过的 IF/THEN 逻辑形式。

James0x57 将这种想法扩展到了所有逻辑可能性,例如 AND、OR、XOR、NAND、NOR 和 XNOR,但这又让我迷茫了。我不是一个真正的计算机科学家。但你可以关注他们的工作,如果你想看到这些东西的实际应用。

这些变量很疯狂,而且非常令人困惑。我在 Patrick Brosset 的一篇可能很新(但署名日期是 2015 年?)文章中注意到了一些关于 CSS 自定义属性的棘手问题。例如,回退可以无限嵌套,比如

color: var(--foo, var(--bar, var(--baz, var(--are, var(--you, var(--crazy)))));

此外,CSS 自定义属性的有效值可以包含逗号,例如

content: var(--foo, one, two, three);

这真的是一个带有一个 one, two, three 值的单一回退吗?这真是令人头疼。

无论如何,现在快进几个月,CSS 技巧大师 Lea Verou 已经将目光瞄准了自定义属性中的空白符。

如果我告诉你,你可以使用一个属性值来打开和关闭多个不同属性(甚至跨多个 CSS 规则)的多个不同值,你会怎样想?

这与之前的技巧相同!不过,在 Lea 的例子中,她使用这种能力来

  • 设置按钮的变体,以及
  • 设置四个不同的属性而不是一个。

这确实突出了这个概念为什么如此酷。

Lea 指出了它的一些缺点

没有办法说“如果 --foo 已设置,则背景应为红色,否则应为白色”。一些这样的条件可以通过巧妙地使用追加来模拟,但大多数情况不行。

当然,还存在一定的可读性问题: --foo: ; 看起来像个错误,而 --foo: initial 看起来也很奇怪,除非你了解这种技术。

我们无疑正在进入自定义属性使用方式的新时代。首先,我们像预处理器变量一样使用它们。然后我们开始看到更多级联和回退的使用。接下来,我们更频繁地将它与 JavaScript 结合使用。现在是这个。

甚至还有更多关于保留 CSS 预处理器变量的文章,不仅仅是在你只需要它们的功能时才保留它们,而是为了保留它们特有的功能,例如操作它们的彩色值。