在网页上轻松使用暗黑模式
这篇文章最初发表在我的博客上
黑暗模式🌒是过去几年的一种趋势,你会发现几乎所有网站都启用了该模式,包括像 Twitter 这样的知名网站,黑暗模式如此受欢迎的主要原因是,在光线不足的地方,人眼在昏暗的背景上看到浅色文字比反之要好得多。
在这篇简短的文章中,我试图向您展示如何使用 CSS 和 JavaScript 轻松实现该功能。
假设
我们有一个小型 HTML 页面,默认情况下具有浅色主题,我们需要实现深色主题以及为访问者提供选项,因此基本上我们可以通过更改 CSS 的变量来轻松做到这一点,无论是 CSS 的自定义属性--primary-color
还是使用 Sass$primary-color
或任何其他方式。
这是浅色主题的样子
解释
让我们首先看一下我们拥有的 CSS 变量(不用担心,整个代码都在文章末尾提到的 GitHub repo 上)
:root {
--primary-bg: #eee;
--primary-fg: #000;
--secondary-bg: #ddd;
--secondary-fg: #555;
--primary-btn-bg: #000;
--primary-btn-fg: #fff;
--secondary-btn-bg: #ff0000;
--secondary-btn-fg: #ffff00;
--image-opacity: 1;
}
// here is the rest of the CSS styles
主要目标是将这些变量值更改为以下内容:
:root {
--primary-bg: #282c35;
--primary-fg: #fff;
--secondary-bg: #1e2129;
--secondary-fg: #aaa;
--primary-btn-bg: #ddd;
--primary-btn-fg: #222;
--secondary-btn-bg: #780404;
--secondary-btn-fg: #baba6a;
--image-opacity: 0.85;
}
仅当我们有dark mode
用户的偏好时,上述变量才是相同的变量名称,只有不同的值才能使主题变暗,因为每当您定义相同的变量两次时,后一个变量就会覆盖第一个变量。
仅使用 CSS 实现
我们有几种方法可以解决这个问题,例如prefers-color-scheme
在 CSS 中使用媒体查询,如果媒体查询匹配,则将启用颜色变量列表,如下所示:
@media (prefers-color-scheme: dark) {
:root {
--primary-bg: #282c35;
--primary-fg: #fff;
--secondary-bg: #1e2129;
--secondary-fg: #aaa;
--primary-btn-bg: #ddd;
--primary-btn-fg: #222;
--secondary-btn-bg: #780404;
--secondary-btn-fg: #baba6a;
--image-opacity: 0.85;
}
}
它在大多数现代浏览器中都得到了很好的支持,当然 IE11 除外。
在这种情况下,您不必为用户实现切换按钮,因为您的网站无论如何都会遵循用户偏好。
User preference
:在现代操作系统中,您可以在设置中将操作系统的常规主题更改为深色或浅色,并通过在 CSS 中添加上述代码,它将从操作系统获取用户偏好,并根据用户的偏好显示网站,这是一个很棒的技巧💫
这是黑暗模式下的样子:
但是,如果用户喜欢以轻量模式预览您的网站而不管操作系统的偏好如何,您可能会遇到一个问题,在这种情况下,您必须实现一个按钮供用户切换到他们自己的偏好。
实现切换按钮 (JavaScript)
让我们首先在 HTML 文件末尾的正文关闭之前添加一个简单的脚本标签,然后在其中选择我们要用作暗模式切换的按钮。
// here is the button
<div id="dark-mode-toggle" title="Dark mode toggle">🌒</div>
... // here is the script tag
<script>
const toggleButton = document.querySelector("#dark-mode-toggle")
</script>
现在我们应该考虑一种方法来保存和保留用户偏好,而最好的解决方案就是localStorage
。
让我们监听该按钮的点击并检查theme
localStorage 中的键值是否将dark
其转换为light
并更改该图标,否则执行相反的操作。
脚本如下:
<script>
const toggleButton = document.querySelector('#dark-mode-toggle');
toggleButton.addEventListener('click', (e) => {
darkMode = localStorage.getItem('theme');
if (darkMode === 'dark') {
disableDarkMode();
} else {
enableDarkMode();
}
});
function enableDarkMode() {
localStorage.setItem('theme', 'dark');
toggleButton.innerHTML = '☀️';
}
function disableDarkMode() {
localStorage.setItem('theme', 'light');
toggleButton.innerHTML = '🌒';
}
</script>
现在我们有一个按钮功能,可以将theme
localStorage 中的键从更改light
为dark
,反之亦然,并且它还可以切换图标来显示某些内容,但是,我们仍然没有达到我们的目标。
这里的想法是创建一个包装类,它将保存暗模式 CSS 变量,并根据条件添加/删除该类,以及在正文中使用的最佳元素。
首先修改 CSS 并创建该类,如下所示:
.dark-mode {
--primary-bg: #282c35;
--primary-fg: #fff;
--secondary-bg: #1e2129;
--secondary-fg: #aaa;
--primary-btn-bg: #ddd;
--primary-btn-fg: #222;
--secondary-btn-bg: #780404;
--secondary-btn-fg: #baba6a;
--image-opacity: 0.85;
}
然后让我们转到脚本来稍微改变一下功能:
function enableDarkMode() {
document.body.classList.add("dark-mode")
localStorage.setItem("theme", "dark")
toggleButton.innerHTML = "☀️"
}
function disableDarkMode() {
document.body.classList.remove("dark-mode")
localStorage.setItem("theme", "light")
toggleButton.innerHTML = "🌒"
}
现在,单击切换按钮后,功能应该可以正常工作,如下所示:
还有一点需要注意的是,如果这是 localStorage 中的设置,则在重新加载时您将无法获得暗模式,解决方案很简单,只需在脚本开头添加它即可。
let darkMode = localStorage.getItem("theme")
if (darkMode === "dark") enableDarkMode()
就是这样,你现在可以走了,但在这种情况下,我们丢失了在使用媒体查询之前实现的用户偏好,好消息是我们可以在 Javascript 中监听它并执行以下操作:
window
.matchMedia("(prefers-color-scheme: dark)")
.addListener(e => (e.matches ? enableDarkMode() : disableDarkMode()))
通过使用上述代码,每当用户改变他的偏好时,您的网站就会遵循这一点,最后我们有一个完整的解决方案,这是完整的脚本标签:
<script>
const toggleButton = document.querySelector("#dark-mode-toggle")
let darkMode = localStorage.getItem("theme")
if (darkMode === "dark") enableDarkMode()
toggleButton.addEventListener("click", e => {
darkMode = localStorage.getItem("theme")
if (darkMode === "dark") {
disableDarkMode()
} else {
enableDarkMode()
}
})
function enableDarkMode() {
document.body.classList.add("dark-mode")
localStorage.setItem("theme", "dark")
toggleButton.innerHTML = "☀️"
}
function disableDarkMode() {
document.body.classList.remove("dark-mode")
localStorage.setItem("theme", "light")
toggleButton.innerHTML = "🌒"
}
window
.matchMedia("(prefers-color-scheme: dark)")
.addListener(e => (e.matches ? enableDarkMode() : disableDarkMode()))
</script>
结论
😅 呼,就是这样,一个简单但重要的解决方案,现在非常流行,您可以在Github repo上找到整个代码示例,我希望您在本快速教程中学到了一些新东西。
如果您需要任何帮助,请随时在 Twitter 上与我分享或讨论,或者关注我并让我们成为朋友。
如果您懂阿拉伯语,这里有阿拉伯语教程中的逐步解释:
https://youtu.be/QC0PMPhq6CM
孩子们👋
文章来源:https://dev.to/medhatdawoud/dark-mode-easily-on-the-web-5h6a