CSS 的新 light-dark() 函数是 2024 年实现暗模式的最佳方式
2024 年终于有了一种仅使用 CSS 的动态主题方法!但首先,让我们谈谈现状。
现状
你知道吗,自 2019 年以来,开发人员只需一行 CSS 就可以为整个站点添加暗模式?只需在 :root
中添加 color-scheme: light dark;
,就可以获得全站暗模式支持——但它只适用于未指定颜色的元素,因此使用默认的浏览器颜色。
如果你想让自定义颜色的暗模式生效(大多数网站都需要),你需要将每个颜色声明包装在笨拙的 @media (prefers-color-scheme: ...)
块中:
@media (prefers-color-scheme: dark) {
body {
color: #fff;
background-color: #222;
}
}
@media (prefers-color-scheme: light) {
body {
color: #333;
background-color: #fff;
}
}
基本上,你需要把每个颜色声明写两遍。糟糕!这种冗长的语法使得编写和维护都很麻烦。因此,尽管 color-scheme
已发布五年,但从未真正流行起来。
引入 light-dark()
2024 年,一切都改变了,随着 light-dark()
的引入。现在,我们可以在同一行中声明浅色和深色主题颜色!
body {
color-scheme: light dark; /* 启用浅色模式和深色模式 */
color: light-dark(#333, #fff); /* 文本浅色和深色颜色 */
background-color: light-dark(#fff, #222); /* 背景浅色和深色颜色 */
}
在这个示例代码中,正文文本在浅色模式下定义为 #333
,在深色模式下定义为 #fff
,而背景色则分别定义为 #fff
和 #222
。就这样!浏览器会根据用户的系统设置自动选择使用哪种颜色。无需 JavaScript 逻辑、自定义类或媒体查询。一切都能正常工作。
可重用、动态主题化的颜色令牌
我们可以通过将 light-dark()
函数分配给 CSS 变量,使事情变得更简单。例如:
:root {
/* 启用浅色模式和深色模式 */
color-scheme: light dark;
/* 将浅色/深色颜色令牌分配到变量中 */
--text-heading: light-dark(#333333, #f0f0f0);
--text-body: light-dark(#555555, #e0e0e0);
--background-primary: light-dark(#ff7d7d, #6f0000);
--background-secondary: light-dark(#fffef3, #1a1913);
}
body {
/* 使用颜色令牌 */
background-color: var(--background-primary);
color: var(--text-body);
}
应用程序的其余部分可以像其他变量一样使用这些 CSS 变量。这使我们的 CSS 更加简洁,同时保持我们的网站的一致性。
顺便说一句,最好选择有意义的功能变量名称,这可以加快开发速度并使我们的应用程序更一致。请参阅我的帖子了解设计令牌的更多信息。
强制页面的一部分使用特定主题
我们还可以轻松地强制页面的一部分仅使用浅色或深色模式,而页面的其余部分继续适应系统设置。
想象一下,我们有一个包含三个部分的页面,我们希望第二部分始终保持在深色模式,因为它使用了深色背景图像。我们只需添加一个具有自己 color-scheme
属性的自定义类即可实现这一点:
<!-- Index.html -->
<main>
<section>
<h1>Heading 1</h1>
<p>Paragraph 1</p>
</section>
<section class="dark-section">
<h1>Heading 2</h1>
<p>Paragraph 2</p>
</section>
<section>
<h1>Heading 3</h1>
<p>Paragraph 3</p>
</section>
</main>
/* Index.css */
:root {
color-scheme: light dark;
--text: light-dark(#333333, #ffffff);
}
.dark-section {
color-scheme: dark;
}
h1 { color: var(--text); }
p { color: var(--text); }
dark-section
类中的 color-scheme: dark
属性将覆盖根中的 color-scheme: light dark
。第二部分将保持在深色模式,而页面的其余部分继续适应系统设置。
示例
你可以在这里找到我所写内容的工作示例: https://codesandbox.io/p/sandbox/hll8p3。玩一玩,如果有任何问题请在下面评论。
总结
总之,light-dark()
使管理浅色和深色主题变得轻而易举。它使我们的 CSS 更加简洁,我们的设计更加用户友好,并确保我们的网站看起来很棒。我毫不怀疑,未来使用 color-scheme
和 light-dark()
将成为行业最佳实践。