本文由 Mads Stoumann 撰写的博文,主要介绍了如何通过简单的三行CSS代码实现网站的暗黑模式。该博文提到,<system-color>
关键字一般反映用户、浏览器或操作系统做出的默认颜色选择。这些关键字通常用于浏览器的默认样式表。通过这种方式,我们可以轻松地实现网站的暗黑模式。
在另一篇博文中,Mads Stoumann详细介绍了如何使用SVG和CSS重新创建Apple的暗黑模式图标。这证明了他在此领域的深厚技术和创新能力。
总的来说,这个网站提供了许多关于使用CSS和SVG进行网站设计和开发的有用信息,特别是关于暗黑模式的实现。这对那些希望在自己的网站上实现暗黑模式的开发者来说是非常有价值的资源。
下面是正文~~
深色模式是一种设计趋势,网站的配色方案被更改为深色背景,配以浅色文字和元素。它也被称为夜间模式或黑暗主题。深色模式的目的是减少低光环境下的眼睛疲劳,节省移动设备的电池寿命,并创造一个时尚现代的美感。
许多热门网站和应用程序现在都提供了黑暗模式选项 —— 如 TailwindCSS:
如果您是开发者,您很可能已经知道如何在开发者工具中切换暗黑模式:
如果你想要为操作系统(以及所有支持暗黑模式的应用程序)切换暗黑模式,请转到系统设置。在Mac上,可以在系统设置>外观下找到它:
使用系统颜色的深色模式
首先,我们将创建一个带有标题的简单HTML:
<body>
<h1>Hello Darkness, My Old Friend</h1>
</body>
在样式表中,添加:
body {
color-scheme: light dark;
}
这会告诉浏览器,document 可以接受亮色和暗色的 color-scheme 。
当前如果现在指定为 dark 浏览器也不会变成黑色。
这是因为 user-agent 样式表没有设置任何默认颜色。我们可以通过使用系统颜色快速解决这个问题:
body {
background-color: Canvas;
color: CanvasText;
color-scheme: light dark;
}
仅用3行CSS代码就能为我们的整个网站实现暗黑模式!
下面,我们更深入地了解系统颜色,来自规范:
一般来说,<system-color>关键字反映了用户、浏览器或操作系统做出的默认颜色选择。由于这个原因,它们通常在浏览器默认样式表中使用。
这是一个浅色模式演示,在Safari中展示了可用的系统颜色:
如果我们切换到深色模式,某些颜色会完全改变(就像我们已经遇到的 Canvas 和 CanvasText ),而其他颜色只会稍微改变:
使用系统颜色进行黑暗模式是一种简化的黑暗模式体验。是的,它会起作用 — 但是纯黑白有点无聊
我们可以在CSS中使用 color-mix 来增加趣味性 将 CanvasText (黑色或白色)混入 Canvas (白色或黑色)以获得 background-color ,反之亦然,用于 color :
body {
background-color: color-mix(in srgb, Canvas, CanvasText 2.5%);
color: color-mix(in srgb, CanvasText, Canvas 15%);
}
这样看起来会更柔和:
从颜色中减去饱和度,是在深色模式中制作颜色变化的一种广泛使用的方法。
在CSS中使用相对颜色,我们可以做到这一点:
background: hsl(from ActiveText h calc(s - 30%) l);
不幸的是,相对颜色在任何浏览器中都不能与系统颜色一起工作。
注意:系统颜色可以被强制颜色覆盖(尽管很少使用)——所以不要过分依赖这种技术。
我们继续学习另一种技巧,这将使我们能够精细控制我们的暗黑模式颜色。
使用 prefers-color-scheme 媒体查询
要为亮色和暗色模式指定特定颜色,我建议使用 CSS 自定义属性,然后使用 prefers-color-scheme 媒体查询更新这些属性。
以浅色模式为默认,我们将颜色添加到 :where(body) -部分,将它们与我们的常规 body -样式分开:
/* Properties */
:where(body) {
--background-color: #FFF;
--text-color: #222;
}
body {
background-color: var(--background-color);
color: var(--text-color);
}
然后,对于暗黑模式,我们将简单地更新这些颜色属性:
@media (prefers-color-scheme: dark) {
:where(body) {
--background-color: hsl(228, 5%, 15%);
--text-color: hsl(228, 5%, 80%);
}
}
但是,如果我们希望用户根据自己的需求选择我们网站的版本,而不是根据系统设置呢?
他们可能更喜欢将系统设置为深色模式,但我们的网站是浅色模式。让我们创建一个切换器!如果您访问像 TailwindCSS 这样的网站,您会注意到当您从 color-scheme-toggler 中选择“dark”时,会在 html -节点上添加一个 dark -类。这是通过 JavaScript 完成的:
创建颜色方案切换器
如果你用过 TailwindCSS ,你会注意到当你从 color-scheme-toggler 中选择“dark”时,会在 html -节点上添加一个 dark -类。这是通过 JavaScript 完成的:
window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
Open Props 正在使用类似的方法,但是更新 data-theme 属性,然后在两个块中定义属性:
[data-theme=light] {
--nav-icon: var(--gray-7); /* etc */
}
[data-theme=dark] {
--nav-icon: var(--gray-5); /* etc */
}
使用 CSS
使用一些全新的CSS技术,我们可以在不使用JavaScript的情况下创建一个切换器。我们将创建一个具有3种状态的切换器:
- Light (forced)
- Auto (system default, could be either light or dark)
- Dark (forced)
首先,一些基本标记:
<fieldset>
<label>
<input type="radio" name="color-scheme" id="color-scheme-light" value="0">
Light
</label>
<label>
<input type="radio" name="color-scheme" value="auto" checked>
Auto
</label>
<label>
<input type="radio" name="color-scheme" id="color-scheme-dark" value="1">
Dark
</label>
</fieldset>
在添加了一些基本样式后(请参阅下面的Codepen演示),它的呈现效果如下:
我们将在html元素中添加一个 --darkmode -属性和 container-type :
html {
--darkmode: 0;
container-name: root;
container-type: normal;
}
我们使用 @container style() -查询,因此我们需要将节点设置为“container”。
既然我们不想观察到 inline-size 变化,我们只需添加值 normal 。
如果用户选择了一个“强制”值,我们将更新 --darkmode :
html:has(#color-scheme-light:checked) { --darkmode: 0; }
html:has(#color-scheme-dark:checked) { --darkmode: 1; }
最后,我们将使用容器 style() -查询来检查,如果 --darkmode 设置为 1 :
@container root style(--darkmode: 1) {
body {
--background-color: hsl(228, 5%, 15%);
--text-color: hsl(228, 5%, 80%);
}
}
注意:@container style() -queries 目前仅在 Chrome 中的 behind-a-flag 下工作,这还是初期阶段,所以不要在生产环境中使用。
现在,在选择“Dark”之后,我们的切换器(和页面)看起来是这样的:
存储状态
如果我们想要存储用户的选择,就需要一点JavaScript!
首先,为 <fieldset> 添加一个标识符:
<fieldset id="colorScheme">
接下来,在JavaScript中:
const colorScheme = document.getElementById('colorScheme')
colorScheme.addEventListener('change', event => {
localStorage.setItem('color-scheme', event.target.value)
})
现在,我们只需要在文档加载后将属性设置为 localStorage -值:
window.addEventListener("load", event => {
const scheme = localStorage.getItem('color-scheme') || 'auto'
if (scheme) {
document.documentElement.style.setProperty('--darkmode', scheme)
}
})
要在切换器中选择正确的模式,请将此添加到 if -块:
const selected = [...colorScheme.elements].filter(element => element.value === scheme)
if (selected) selected[0].checked = true;
Toggler
事例:https://codepen.io/stoumann/pen/KKGNbQr
System Colors
https://codepen.io/stoumann/pen/GRYNPzy。