暗黑模式已经成为现代网页的标配功能之一,用户可以根据自己的使用场景切换亮色或暗色主题,减少长时间浏览的视觉疲劳。HTML5结合CSS3的新特性,可以非常便捷地实现完整的主题切换能力,不需要依赖复杂的第三方库。

实现暗黑模式的核心原理
主题切换的核心思路是定义多套主题对应的样式变量,通过切换根节点或者特定容器的类名,改变变量的取值,从而让页面样式整体发生变化。CSS自定义属性(也就是CSS变量)是实现这个功能的基础,它允许我们在样式表中定义可复用、可动态修改的值。
1. 定义CSS主题变量
我们首先在根选择器:root中定义亮色主题的默认变量,再单独定义一个暗色主题的类名,在这个类名下覆盖变量的取值。这样只要给根节点添加对应的类名,就能切换所有使用这些变量的样式。
/* 定义默认亮色主题变量 */
:root {
--bg-color: #ffffff;
--text-color: #333333;
--card-bg: #f5f5f5;
--border-color: #e0e0e0;
}
/* 定义暗色主题变量 */
.dark-theme {
--bg-color: #1a1a1a;
--text-color: #e0e0e0;
--card-bg: #2d2d2d;
--border-color: #444444;
}
2. 页面样式使用变量
定义好变量之后,页面中的所有样式都使用这些变量来设置颜色相关属性,而不是直接写固定的颜色值。这样后续切换主题时,只需要修改变量的取值,所有关联样式都会自动更新。
/* 页面基础样式使用变量 */
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
}
.card {
background-color: var(--card-bg);
border: 1px solid var(--border-color);
padding: 16px;
border-radius: 8px;
}
实现主题切换的完整逻辑
有了样式基础之后,还需要编写JavaScript逻辑来实现切换功能,同时要把用户的选择存储到本地,避免用户刷新页面后主题重置。
1. 切换主题的JavaScript代码
切换逻辑很简单,就是给html根节点添加或者移除dark-theme类名,同时把当前主题状态存储到localStorage中。
// 获取根节点
const rootElement = document.documentElement;
// 获取切换按钮
const themeToggleBtn = document.getElementById('theme-toggle');
// 初始化主题:优先读取本地存储的主题,没有则使用系统偏好
function initTheme() {
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
rootElement.classList.toggle('dark-theme', savedTheme === 'dark');
} else {
// 检测系统是否偏好暗色模式
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
rootElement.classList.toggle('dark-theme', prefersDark);
}
}
// 切换主题的函数
function toggleTheme() {
const isDark = rootElement.classList.toggle('dark-theme');
// 存储当前主题到本地
localStorage.setItem('theme', isDark ? 'dark' : 'light');
}
// 初始化主题
initTheme();
// 绑定切换按钮点击事件
themeToggleBtn.addEventListener('click', toggleTheme);
2. 切换按钮的HTML结构
页面中只需要添加一个简单的切换按钮,按钮的图标可以根据当前主题动态变化,这里我们用简单的文本表示,也可以替换为图标字体或者SVG。
<button id="theme-toggle"> 切换主题 </button> <div class="card"> 这是一张卡片内容,用于展示主题切换的效果 </div>
优化与扩展
基础功能实现之后,还可以做一些优化提升用户体验。比如给主题切换添加过渡动画,避免颜色突变过于生硬;监听系统主题变化,当用户修改系统主题时,网页也同步更新;还可以扩展更多主题,不止亮色和暗色两种,只需要定义更多的主题类名和对应的变量即可。
另外需要注意,如果页面中有图片等不需要跟随主题变化的内容,可以单独给这些内容设置固定的样式,避免主题切换时影响内容的展示效果。
常见问题解答
- 切换主题后刷新页面重置怎么办? 只要按照上面的逻辑把主题状态存储到
localStorage,初始化时读取存储的值就可以解决。 - 如何兼容不支持CSS变量的旧浏览器? 可以使用PostCSS等工具把CSS变量编译为固定的属性值,或者给不支持的浏览器提供默认的亮色主题。
- 切换时样式闪烁怎么处理? 可以在页面加载完成前就读取本地存储的主题并添加对应的类名,避免页面先展示默认主题再切换的闪烁问题。