JavaScript通过document.documentElement.style.setProperty()动态修改:root下的CSS变量实现主题切换,配合var()引用和localStorage持久化,支持降级兼容。

JavaScript中通过CSS变量实现动态主题切换,核心是用document.documentElement.style.setProperty()修改根元素(:root)定义的CSS变量,再配合CSS中的var(--xxx)引用,让样式自动响应变化。
1. 在CSS中定义主题相关的CSS变量
把颜色、字体、间距等可变值抽成:root下的CSS变量,不同主题只需覆盖对应变量:
:root {
--primary-color: #007bff;
--bg-color: #ffffff;
--text-color: #333333;
--border-color: #e0e0e0;
}
<p>[data-theme="dark"] {
--primary-color: #0056b3;
--bg-color: #1a1a1a;
--text-color: #f0f0f0;
--border-color: #333333;
}也可以不依赖属性选择器,全部用:root定义,JS直接覆盖:
:root {
--primary-color: #007bff;
--bg-color: #ffffff;
--text-color: #333333;
}2. JS中动态设置CSS变量
用document.documentElement.style.setProperty()修改变量值,所有引用该变量的元素会实时更新:
立即学习“Java免费学习笔记(深入)”;
- 切换深色模式示例:
function setDarkTheme() {
document.documentElement.style.setProperty('--primary-color', '#0056b3');
document.documentElement.style.setProperty('--bg-color', '#1a1a1a');
document.documentElement.style.setProperty('--text-color', '#f0f0f0');
}- 批量设置更简洁:用
Object.entries()遍历对象
function applyTheme(theme) {
Object.entries(theme).forEach(([prop, value]) => {
document.documentElement.style.setProperty(prop, value);
});
}
<p>applyTheme({
'--primary-color': '#ff6b6b',
'--bg-color': '#2d2d2d',
'--text-color': '#e0e0e0'
});3. 保存用户偏好并初始化主题
避免每次刷新重置,建议读取本地存储并在页面加载时应用:
- 保存主题到
localStorage:
function saveTheme(themeName) {
localStorage.setItem('preferred-theme', themeName);
}- 页面加载时恢复主题:
function initTheme() {
const saved = localStorage.getItem('preferred-theme');
if (saved === 'dark') {
setDarkTheme();
} else {
setLightTheme();
}
}
document.addEventListener('DOMContentLoaded', initTheme);4. 配合class或data属性做兼容性兜底
CSS变量在旧浏览器(如IE)不支持,可用data-theme或class配合传统CSS规则降级:
body[data-theme="dark"] .card {
background: #1a1a1a;
color: #f0f0f0;
}
<p>/<em> 同时使用变量和fallback </em>/
.card {
background: #ffffff;
background: var(--bg-color);
color: #333333;
color: var(--text-color);
}JS中同步设置data-theme属性,确保降级样式生效:
document.documentElement.setAttribute('data-theme', 'dark');不复杂但容易忽略:CSS变量区分大小写,JS中传入的变量名必须和CSS里定义的一致(包括--前缀),且不能有空格或特殊字符。主题切换本质是“改变量→CSS自动重算”,无需操作DOM节点样式,轻量高效。


















