如何通过JavaScript切换SCSS中@import 'light'与'dark'实现深色模式?
解决SASS架构下的深色模式切换问题
首先得明确:你想通过JavaScript修改.scss文件的@import语句是行不通的——SASS是预编译语言,所有变量替换、文件导入都是在编译阶段完成的,编译后生成的是纯CSS文件,运行时JS根本碰不到未编译的.scss源文件。
下面是可行的实现方案,兼顾SASS的变量管理和前端动态切换需求:
1. 用SASS变量映射CSS自定义属性
把浅色、深色模式的SASS变量,映射到全局可动态修改的CSS变量上:
- 创建
_variables.scss文件,定义两套主题变量并映射:
// 浅色模式变量 $light-bg: #ffffff; $light-text: #000000; // 深色模式变量 $dark-bg: #000000; $dark-text: #ffffff; // 全局CSS变量:默认浅色模式 :root { --bg-color: #{$light-bg}; --text-color: #{$light-text}; } // 深色模式下的CSS变量覆盖 [data-theme="dark"] { --bg-color: #{$dark-bg}; --text-color: #{$dark-text}; }
- 在
main.scss中导入这个变量文件,所有组件直接使用CSS变量:
@import 'variables'; body { background-color: var(--bg-color); color: var(--text-color); // 可选:添加过渡动画让切换更平滑 transition: background-color 0.3s ease, color 0.3s ease; } // 其他组件示例 .header { background-color: var(--bg-color); border-bottom: 1px solid var(--text-color); }
2. 用JavaScript切换主题状态
通过修改根元素的data-theme属性,触发CSS变量的切换,同时保存用户的主题偏好:
// 获取切换按钮(假设按钮ID是theme-toggle) const themeToggle = document.getElementById('theme-toggle'); // 初始化主题:优先用本地存储的偏好,没有则跟随系统深色模式 const savedTheme = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; const initTheme = savedTheme || (prefersDark ? 'dark' : 'light'); document.documentElement.setAttribute('data-theme', initTheme); // 绑定切换事件 themeToggle.addEventListener('click', () => { const currentTheme = document.documentElement.getAttribute('data-theme'); const newTheme = currentTheme === 'light' ? 'dark' : 'light'; // 修改根元素属性 document.documentElement.setAttribute('data-theme', newTheme); // 保存到本地存储,下次打开页面自动应用 localStorage.setItem('theme', newTheme); });
3. 可选:拆分主题变量文件
如果想把浅色、深色变量分开维护,可创建_light.scss和_dark.scss,再在_variables.scss中统一导入映射:
_light.scss:
$bg: #ffffff; $text: #000000;
_dark.scss:
$bg: #000000; $text: #ffffff;
_variables.scss:
// 导入浅色变量并映射到默认CSS变量 @import 'light'; :root { --bg-color: #{$bg}; --text-color: #{$text}; } // 导入深色变量并映射到深色模式下的CSS变量 @import 'dark'; [data-theme="dark"] { --bg-color: #{$bg}; --text-color: #{$text}; }
这种方案既保留了SASS变量的便捷性,又实现了运行时的动态主题切换,完全不需要修改.scss的@import语句。
内容的提问来源于stack exchange,提问作者user21234841
相关产品推荐
相关产品推荐

