一开始的思路是通过 Less 变量作用范围 来切换 light
和 dark
主题,但 Less 本身不会动态监听类名变化,所以直接这样写是 不可行的,因为 Less 是 预处理语言,它在编译阶段就确定了 @color
的值,而不是在运行时动态切换。
如何让 Less 变量支持暗黑模式切换?
你可以使用 CSS 变量(var(--color)
) 来代替 Less 变量,并结合 document.documentElement.classList.add('dark')
动态切换类名。
✅ 方案:结合 Less + CSS 变量
// 定义默认(light)模式
:root {
--color: white;
}
// 定义 dark 模式
.dark {
--color: black;
}
// 使用 Less 变量引用 CSS 变量
@color: var(--color);
.box {
background-color: @color;
color: var(--text-color, black); // 可选:防止没有定义时默认使用黑色
}
???? 解析
- 在
:root
作用域内定义 CSS 变量--color: white;
(默认白色)。 - 当
html
具有class="dark"
时,CSS 变量--color
变为black
。 -
Less 变量
@color
只是引用var(--color)
,这样它不会在编译时固化,而是允许 CSS 变量在运行时动态切换。
✅ JS 控制主题
document.getElementById("theme-toggle").addEventListener("click", () => {
document.documentElement.classList.toggle("dark");
});
这样,当 documentElement
添加 dark
类后,--color
变量就会改变,所有使用 @color
的地方都会自动更新颜色!
✅ 这样做的好处
- CSS 变量在运行时动态切换,不需要重新编译 Less。
-
Less 代码仍然保持简洁,可以继续使用
@color
变量来管理颜色。 - 兼容性好,适用于所有支持 CSS 变量的浏览器(现代浏览器基本都支持)。
❌ 为什么 @color: white;
直接这样写不可行?
.light {
@color: white;
}
.dark {
@color: black;
}
原因:
-
Less 变量是静态编译的,它不会随
class
变化而动态修改。 - 变量
@color
只会在 Less 预编译时解析一次,不会响应class="dark"
的变化。
???? 最终推荐方案
:root {
--color: white;
}
.dark {
--color: black;
}
@color: var(--color);
.box {
background-color: @color;
}
然后用 JS 来切换:
document.documentElement.classList.toggle("dark");
这样 Less 变量就能动态切换颜色了!????