Less变量无法运行时切换,必须通过CSS自定义属性(如--primary-color)实现换肤:Less编译时用~"var(--primary-color, #007bff)"保留var()函数,JS在:root上动态修改CSS变量,主题文件需优先@import且禁用Less对CSS变量的运算。

Less变量不能在运行时动态切换,必须预编译
Less 是编译时语言,所有 @color-primary 这类变量在构建阶段就被替换成固定值,生成的 CSS 里根本不存在“变量”概念。想靠 JS 修改 Less 变量实现换肤?不可能——浏览器只认识 CSS,不认 Less 源码。
所以真正可行的路径只有一条:用 CSS 自定义属性(--primary-color)承接主题色,再让 Less 在编译时把它们作为默认值注入。
- Less 文件里用
@primary-color: var(--primary-color, #007bff);声明“回退到 CSS 变量” - 所有组件样式基于这类变量定义,例如
background-color: @primary-color; - 最终生成的 CSS 会保留
var(--primary-color, #007bff),JS 才能 runtime 修改
如何让 Less 编译后仍保留 var() 函数调用
Less 默认会尝试计算 var() 表达式(比如报 variable @xxx is undefined),必须阻止它解析,强制输出原样。
- 用双引号包裹:写成
@primary-color: "var(--primary-color, #007bff)";—— 但这样后续无法参与颜色函数运算(如darken(@primary-color, 10%)会失败) - 更稳妥的做法是用
~"var(--primary-color, #007bff)",波浪号表示转义字符串,Less 不解析、不报错,且支持拼接 - 如果需要颜色变换,得改用 CSS 原生方案:把
darken()拆成两个 CSS 变量,例如--primary-color-dark,由 JS 同步更新
主题切换时,JS 修改 CSS 变量的正确姿势
直接 document.documentElement.style.setProperty('--primary-color', '#ff6b6b') 是基础操作,但容易漏掉几个关键点:
立即学习“前端免费学习笔记(深入)”;
- 必须在
:root上设置,否则子元素可能因继承链断裂而失效 - 深色模式等复杂主题建议用 class 切换:
document.documentElement.classList.toggle('theme-dark'),再通过.theme-dark { --primary-color: #4a5568; }控制 - 注意 SSR 场景:服务端渲染时无法执行 JS,需提前注入对应 class 或内联 style,否则首屏闪动
- 避免逐个 setProperty,应批量写入 style 标签或使用
CSSStyleSheet.replace()提升性能
Less + CSS 变量混合开发时最容易踩的坑
最常被忽略的是 Less 的作用域和覆盖逻辑:
-
@import顺序决定变量优先级,主题变量文件必须在所有组件之前@import,否则组件里写的硬编码色值会覆盖 CSS 变量 - 不要在 Less 中对 CSS 变量做算术运算(如
@primary-light: @primary-color + #222),Less 无法解析,会报错或静默失败 - VS Code 的 Less 插件可能高亮
var(--x)为错误,这是误报,只要用了~""就安全 - Webpack 的
less-loader默认开启javascriptEnabled: false,若用了~"var(...)"则必须设为true,否则编译失败
换肤不是改几行 Less 就能搞定的事,核心在于分清编译期和运行期职责——Less 负责结构和默认值,CSS 变量负责动态响应,JS 负责状态同步。三者边界模糊的地方,就是 bug 最爱藏身的位置。


















