自定义深色模式切换:支持系统跟随与手动切换的方案问询
实现支持系统跟随/手动切换的深色模式
1. 重写Tailwind的dark变体
要让dark:变体同时在.system(跟随系统)和.dark类下生效,需要自定义dark变体的触发条件,替换默认的prefers-color-scheme媒体查询逻辑:
@custom-variant dark (:where(.dark &, .system:is(@media (prefers-color-scheme: dark)) &));
这个规则的作用是:
- 当父级/根元素有
.dark类时,当前元素的dark:变体样式生效 - 当父级/根元素有
.system类,且系统偏好深色模式时,当前元素的dark:变体样式生效
2. 用JavaScript控制主题切换与初始化
需要处理默认主题加载、用户手动切换,以及系统主题变化的同步:
// 初始化主题状态 function initTheme() { const root = document.documentElement; const savedTheme = localStorage.getItem('theme'); // 优先使用用户之前保存的设置,默认用system模式 if (savedTheme) { root.classList.add(savedTheme); } else { root.classList.add('system'); } // 监听系统主题变化,仅在system模式下同步状态 const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); function updateSystemTheme() { if (root.classList.contains('system')) { root.setAttribute('data-theme', mediaQuery.matches ? 'dark' : 'light'); } } mediaQuery.addEventListener('change', updateSystemTheme); updateSystemTheme(); // 初始执行一次 } // 切换主题的核心函数 function switchTheme(theme) { const root = document.documentElement; // 移除所有主题类 root.classList.remove('system', 'light', 'dark'); // 添加选中的主题类 root.classList.add(theme); // 保存到本地存储 localStorage.setItem('theme', theme); } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', initTheme);
3. 页面中添加切换按钮
在HTML里添加触发切换的按钮,绑定switchTheme函数:
<button onclick="switchTheme('system')">跟随系统</button> <button onclick="switchTheme('light')">浅色模式</button> <button onclick="switchTheme('dark')">深色模式</button>
效果说明
- 添加
.system类:自动跟随系统的配色偏好变化,系统切深色则dark:变体生效,切浅色则失效 - 添加
.light类:强制使用浅色主题,dark:变体完全不生效 - 添加
.dark类:强制使用深色主题,dark:变体始终生效
内容的提问来源于stack exchange,提问作者rozsazoltan
相关产品推荐
相关产品推荐

