在CSS中实施光模式和暗模式切换背后的挑战的一个普遍观点是,它似乎需要复制您的-var声明才能设置类。
不是 - 它是一个很容易实现的模式!
一个简短的历史
举例来说,this article from Bramus在2022年5月指出了共同的观点:
尽管在撰写该文章时,它被广泛地接受为真理,但围绕复制 [1] 的实际主题颜色价值有很多方法,这是关注点的大部分。但是...这些方法也留出了改进的空间。
找到了改进,并在所有浏览器中工作 [2] - 除了Safari -until Safari 16.4, around March 2023开始在任何地方工作时!
ps:Bramus is great, follow him!
所需的API
首先,社区最大的问候是,我们可以从实际的媒体偏好中完成所有这些,而无需复选框黑客攻击或使JS在负载上切换以翻转状态,而that work is underway now!
与此同时,即使在实施之后,也很高兴拥有除了偏好之外管理课程的灵活性。
这是API:
- 默认情况下黑暗
-
@media (prefers-color-scheme: light)
root and of of of preference -
.theme-preferred
基于默认的root preferference渲染此节点(&desc。) -
.theme-not-preferred
将此节点(&desc。)渲染为默认根本偏好的对立 -
.theme-dark
在黑暗中呈现此节点(&desc。) -
.theme-light
在光中渲染此节点(&desc。)
然后,将其混合并匹配该API。任何部分或元素,无论父母或偏好是什么,您都可以通过偏好或直接管理光/黑暗来切换。
例如,这将完全按照预期的方式渲染:
<div class="theme-dark">
<span>render dark</span>
<div class="theme-light">render light</div>
</div>
这也是如此:
<main class="theme-preferred">
preferred theme here even if body or html changed it
<div class="theme-light">light</div>
<div class="theme-dark">dark</div>
<section class="theme-not-preferred">
render the opposite of the preference
<div class="theme-preferred">render the preference</div>
<div class="theme-light">light</div>
<div class="theme-dark">dark</div>
</section>
</main>
干燥的实施
如果您不熟悉太空切换,则可以在没有任何技术知识的情况下复制粘贴此设置;初始设置后您不必使用它们。
遵循模式将使您充分利用它!
如果您有兴趣,you can read about space toggles here from when I first invented the idea或Google Google以自那时以来就已经出现的许多文章和演讲!
简而言之,您将灯开关添加到其他值。如果开关是一个空间(ON),则使用旁边的值,如果是
initial
(off),则未使用该值,而后备将其放置在引用时。(是的,是规格!)
样板
首先,将其完全按原样复制。无论您需要在主题之间切换多少个变量,此引擎都不会改变并且完成所有工作:
.theme-not-preferred,
.theme-light {
--media-prefers-light: ;
}
.theme-preferred,
.theme-dark {
--media-prefers-light: initial;
}
@media (prefers-color-scheme: light) {
:root,
.theme-preferred {
--media-prefers-light: ;
}
.theme-not-preferred {
--media-prefers-light: initial;
}
}
这设置了一个--media-prefers-light
空间切换,该切换按照前面描述的我们所需的API翻转。 (互相设置和空间切换是彼此进行的;请查看css-media-vars,以获取整体收集以及它们提供的巨大改进!)
您的主题价值观
接下来,我们将仅设置3个主题依赖性变量来建立模式:
:root,
.theme-preferred,
.theme-not-preferred,
.theme-light,
.theme-dark {
/* (toggle) + Light Values: */
--theme_0_light: var(--media-prefers-light) 0 0% 100%;
--theme_1_light: var(--media-prefers-light) 0 0% 0%;
--theme_2_light: var(--media-prefers-light) hotpink;
/* (toggled_light_value, fallback to Dark Values */
--theme-0: var(--theme_0_light, 0 0% 0%);
--theme-1: var(--theme_1_light, 0 0% 100%);
--theme-2: var(--theme_2_light, rebeccapurple);
}
您不会直接使用--theme_1_light
的光var,它们仅是内部var(因此强调命名约定)来设置您实际想在任何地方使用的var,--theme-1
等。
用法
最后,您要做的就是在CSS中使用主题变量:
.my-info-box-component {
background: hsl(var(--theme-0));
color: hsl(var(--theme-1));
border: 1px solid var(--theme-2);
padding: 1rem;
}
然后,它在所有API方案中都可以在您的HTML中工作:
<aside class="my-info-box-component">
My border is:<br>
- `hotpink` with light mode preference<br>
- `rebeccapurple` with dark mode preference.
</aside>
和:
<aside class="my-info-box-component theme-not-preferred">
My border is:<br>
- `rebeccapurple` with light mode preference<br>
- `hotpink` with dark mode preference.
</aside>
和这个:
<section class="theme-not-preferred">
...
<aside class="my-info-box-component">
My border is:<br>
- `rebeccapurple` with light mode preference<br>
- `hotpink` with dark mode preference.
</aside>
...
<aside class="my-info-box-component theme-preferred">
My border is:<br>
- `hotpink` with light mode preference<br>
- `rebeccapurple` with dark mode preference.
</aside>
</section>
当然也是:
<aside class="my-info-box-component theme-dark">
My border is `rebeccapurple`
</aside>
<section class="theme-dark">
<div>
...
<div>
...
<div>
...
<aside class="my-info-box-component">
My border is `rebeccapurple`
</aside>
...
</div>
...
</div>
...
</div>
</section>
方案测试 /演示Codepen
结束!
如果您认为这很有用,那是我一直很开心的事情!因此,请考虑在这里关注我and on X!
ð½ð
//简·奥里
ps:我最近被解雇了,正在寻找工作!
https://linkedin.com/in/JaneOri
在13年的完整堆栈(主要是JS)工程工作和咨询中,为正确的机会做好了准备!
[1]“围绕复制的方式” - 如果您想要像本文所示的Space Toggle驱动API一样,您确实必须重复一些可变工作,但是可以避免主要关注的问题;实际主题颜色值无重复。 DRY Theme color values, version that works in all browsers
[2]改进的版本“在除Safari以外的所有浏览器中都起作用” - 本文中描述的方法在Firefox和Chrome中工作了很多年,但是因为Safari从技术上可以根据CSS Spec,FF&对其进行正确的处理。 Chrome“修复”以彼此协调(因此所有3个主要浏览器都处于和谐相处),然后为了响应I filed an issue以更改规格,成功地使所有各方同意(再次打破和谐),CSS规格更改了以描述以前作为新规格的行为,FF和Chrome在步骤中恢复为先前的行为,AAAND SAFARI稍后更新,从而产生了新的,改进的,和谐!