
媒体查询5级规范包含一个新的 prefers-color-scheme媒体功能。
目前所有的主要浏览器都支持这个功能。Chrome/Edge自76版起,Firefox自67版起,Safari(自12.1版)。甚至是iOS Safari。
我们可以用它来判断用户是在黑暗还是光明模式下浏览网页。
@media (prefers-color-scheme: dark) {
body {
background-color: black;
color: white;
}
}
@media (prefers-color-scheme: light) {
body {
background-color: white;
color: black;
}
}
我现在用它来显示网站的默认浅色版本,如果系统是在黑暗模式下,则显示深色版本。
如果系统没有内置黑暗模式(老式Windows / macOS,Linux),那么我的建议是使用像Night Eye或类似的扩展。
在prefers-color-scheme ,我是如何实现黑暗模式的
我最近重新设计了我的网站。这里有两张图片是它的样子,供参考。


我在近一年前设计了这个网站,并在此过程中做了许多改动,就像我们做任何网站一样。
最终我对这个设计感到厌倦:标题太大,失去了太多的空间,而不是直接显示内容,等等。
昨天晚上我坐下来,开始重新设计网站,今天早上我完成了重新设计。


好多了!内容,最重要的东西,更加突出。
我使用了一种单行字体(Inconsolata),因为作为一个编程博客,它是一个不错的字体,尽管由于字体的使用,可读性降低,页面大小增加,因为我想在我的网站上使用这种字体。我比较喜欢它,由于我的网站是我日常活动的一个重要部分,我希望它能像我想要的那样。
我只是错过了一件事:黑暗模式。当我在重新设计的过程中,我想到了黑暗模式的选项。
我是怎么做的呢?首先,我在侧边栏中添加了Moon Emoji 🌓,作为一种让人们将模式从浅色变为深色的方式。
然后,我添加了一个JavaScript片段,当它被点击时运行。我只是把它添加到HTML中的onclick 事件处理程序中,而没有进行更复杂的处理。
<p>
<a href="#" onclick="localStorage.setItem('mode', (localStorage.getItem('mode') || 'dark') === 'dark' ? 'light' : 'dark'); localStorage.getItem('mode') === 'dark' ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')" title="Dark/light
</p>
这是运行于onclick的JavaScript。
localStorage.setItem('mode', (localStorage.getItem('mode') || 'dark') === 'dark' ? 'light' : 'dark'); localStorage.getItem('mode') === 'dark' ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')
这有点复杂,但基本上我检查本地存储中的mode 属性是否为 "dark"(如果还没有设置,则默认为dark,使用|| 操作符),并在本地存储中设置与之相反的属性。
然后我把dark 类分配给body HTML元素,这样我们就可以使用CSS来为页面设置暗色模式的样式。
另一个脚本在DOM加载时立即运行,并检查模式是否为暗色。如果是,它就把dark 类添加到body HTML元素中。
document.addEventListener('DOMContentLoaded', (event) => {
((localStorage.getItem('mode') || 'dark') === 'dark') ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')
})
现在,如果人们改变模式,他们的选择将在下次加载页面时被记住。
然后,我在CSS中添加了很多CSS指令,都以body.dark 为前缀。像这些。
body.dark {
background-color: rgb(14,20,10);
color: #fff;
}
body.dark code[class*=language-],
body.dark table tbody>tr:nth-child(odd)>td,
body.dark table tbody>tr:nth-child(odd)>th {
background: #282c34
}
现在事情应该已经开始工作了这是我在黑暗模式下的网站。


我把dark 类默认添加到body 元素中,以使黑暗模式成为默认模式。
<body class="dark">
...
</body>
为什么?首先,我更喜欢它。然后,我在Twitter上做了一个投票,人们更喜欢它。

但也有一个技术原因,实际上是一个非常简单的原因。我不在服务器端存储用户的选择,所以在本地存储之前,我没有办法知道模式的情况。
如果网站是在服务器端生成的,我可以做到这一点,但这是一个静态网站,所以我总是向每个请求它的人提供相同的页面。即使我得到了一个cookie,我也没有地方去处理它(从另一个角度看,这意味着我的页面加载速度更快)。
因此,当有人在我的网站上导航到另一个页面,或在第二次访问时首次加载该页面时,我不想在确定模式时显示一个明亮的页面。也许访问者是在半夜里在一个黑暗的房间里编码的。
我宁愿在光明模式下这样做:显示一个黑暗的页面几毫秒,然后再把它变成白色。