最近,Florens Verschelde 询问了如何在类和媒体查询中定义暗模式样式,同时避免重复声明CSS自定义属性。我过去也遇到过这个问题,但没有找到合适的解决方案。
我们的目标是避免在切换明暗模式时重新定义——从而重复——自定义属性。这是DRY(Don't Repeat Yourself)编程的目标,但切换主题的典型模式通常是这样的:
<code>:root { --background: #fff; --text-color: #0f1031; /* etc. */ } @media (prefers-color-scheme: dark) { :root { --background: #0f1031; --text-color: #fff; /* etc. */ } }</code>
明白我的意思了吗?当然,在这个简短的例子中,它可能看起来并不重要,但想象一下一次处理几十个自定义属性——这是大量的重复!
然后我想起了Lea Verou 使用 --var: ;
的技巧,虽然一开始我没有想到,但我找到了一种方法让它工作:不是用 var(--light-value, var(--dark-value))
或类似的嵌套组合,而是并排使用它们!
当然,肯定有人比我先发现这一点,但我还没有听说过利用(或者更确切地说,是滥用)CSS自定义属性来实现这一点。话不多说,这就是这个想法:
<code>--color: var(--light, orchid) var(--dark, rebeccapurple);</code>
如果 --light
值设置为 initial
,则将使用回退值(orchid),这意味着 --dark
应设置为空格字符(这是一个有效值),使最终计算值如下所示:
<code>--color: orchid ; /* 注意额外的空格 */</code>
相反,如果 --light
设置为空格,而 --dark
设置为 initial
,我们最终得到一个计算值为:
<code>--color: rebeccapurple; /* 同样,注意空格 */</code>
现在,这很好,但我们需要根据上下文定义 --light
和 --dark
自定义属性。用户可以设置系统首选项(明或暗),也可以使用某些UI元素切换网站的主题。就像Florens的例子一样,我们将定义这三种情况,并使用Lea提出的“on”和“off”常量进行一些小的可读性增强,以便一目了然:
<code>:root { /* 感谢Lea Verou!*/ --ON: initial; --OFF: ; } /* 默认情况下,浅色主题处于启用状态 */ .theme-default, .theme-light { --light: var(--ON); --dark: var(--OFF); } /* 默认情况下,暗色主题处于禁用状态 */ .theme-dark { --light: var(--OFF); --dark: var(--ON); } /* 如果用户偏好暗色,那么他们将获得暗色主题 */ @media (prefers-color-scheme: dark) { .theme-default { --light: var(--OFF); --dark: var(--ON); } }</code>
然后,我们可以在一个声明中设置所有主题变量,而无需重复。在这个例子中,theme-*
类被设置为 html
元素,所以我们可以使用 :root
作为选择器,就像许多人喜欢做的那样,但如果自定义属性的级联特性更有意义,你也可以将它们设置为 body
。
<code>:root { --text: var(--light, black) var(--dark, white); --bg: var(--light, orchid) var(--dark, rebeccapurple); }</code>
要使用它们,我们使用 var()
并内置回退,因为我们喜欢小心谨慎:
<code>body { color: var(--text, navy); background-color: var(--bg, lightgray); }</code>
希望您已经开始看到这里的好处了。我们不是定义和切换大量的自定义属性,而是处理两个属性,并在 :root
上只设置其他所有属性一次。这与我们开始的地方相比有了巨大的改进。
使用预处理器实现更DRY的代码
如果让我脱离上下文来看下面这行代码,我肯定会感到困惑,因为颜色是一个单一的值,而不是两个!
<code>--text: var(--light, black) var(--dark, white);</code>
这就是为什么我更喜欢稍微抽象一下。我们可以使用我们最喜欢的预处理器(在我的例子中是Sass)来设置一个函数。如果我们保留上面定义的 --light
和 --dark
值在不同上下文中的代码,我们只需要更改实际的自定义属性声明即可。让我们创建一个 light-dark
函数,它为我们返回CSS语法:
@function light-dark($light, $dark) { @return var(--light, #{ $light }) var(--dark, #{ $dark }); }
我们将像这样使用它:
:root { --text: #{ light-dark(black, white) }; --bg: #{ light-dark(orchid, rebeccapurple) }; --accent: #{ light-dark(#6d386b, #b399cc) }; }
你会注意到在函数调用周围有插值分隔符 #{ … }
。如果没有这些,Sass 将按原样输出代码(就像普通的CSS函数一样)。您可以尝试各种实现方法,但语法复杂性取决于您的喜好。
这对于一个更DRY的代码库来说怎么样?
多于一个主题?没问题!
您可以使用两种以上的模式来实现这一点。您添加的主题越多,管理起来就越复杂,但关键是这是可能的!我们添加另一组ON或OFF变量的主题,并在值列表中设置一个额外的变量。
<code>.theme-pride { --light: var(--OFF); --dark: var(--OFF); --pride: var(--ON); } :root { --text: var(--light, black) var(--dark, white) var(--pride, #ff8c00) ; /* 换行符是完全有效的 */ /* 其他要声明的变量… */ }</code>
这是个技巧吗?是的,绝对是。这是对潜在的、尚不存在的CSS布尔值的很好的用例吗?好吧,这是梦想。
你呢?你是否用不同的方法解决了这个问题?请在评论中分享!
以上是在CSS中为主题着色的干方法的详细内容。更多信息请关注PHP中文网其他相关文章!

您是否曾经在项目上需要一个倒计时计时器?对于这样的东西,可以自然访问插件,但实际上更多


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

Atom编辑器mac版下载
最流行的的开源编辑器