less变量无法运行时切换,必须通过@primary-color: var(--primary-color, #007bff)桥接css变量,再由js修改:root或html上的类或属性触发重计算,因less在构建期已将变量替换为固定值。

Less变量本身不能运行时切换,必须通过var(--xxx)桥接到CSS变量,再由JS修改:root或html上的属性/类来触发重计算。
为什么@primary-color: #007bff无法直接响应主题切换
Less在构建阶段就替换了所有@xxx变量,生成的CSS里根本不存在“变量”——只有固定值。比如background: @primary-color最终编译成background: #007bff,后续JS改任何东西都无效。
- 常见错误现象:
.dark { @primary-color: #222; }写在Less里完全没用,编译后不会生成对应规则 - 变量作用域陷阱:Less变量不继承、不级联,
.theme-dark { @bg: #111; }里的@bg只在该块内有效,且仍是编译期静态值 - 调试盲区:浏览器开发者工具里查不到
@xxx,只能看到最终CSS值,误以为“变量没生效”,其实是根本没参与运行时流程
@color: var(--primary-color)才是正确引用姿势
这行代码不是“定义变量”,而是把CSS变量的运行时求值能力“借给”Less,让@color成为var(--primary-color)的别名。它本身不固化值,每次渲染都重新读取--primary-color当前值。
- 必须写在全局作用域(如
variables.less顶部),不能嵌套在.dark {}里,否则编译会报variable is undefined - 不能省略
var():写成@color: --primary-color是错的,浏览器不认识这个语法 - fallback要显式写:
@color: var(--primary-color, #007bff),否则--primary-color未定义时会退化为inherit或transparent - 示例:
@primary-color: var(--primary-color, #007bff);<br>.btn { background-color: @primary-color; }编译后就是.btn { background-color: var(--primary-color, #007bff); }
如何让--primary-color真正可变
CSS变量必须定义在能被继承的祖先节点上,且需用JS控制其变更时机和范围。最稳妥的是挂载到:root或html元素。
- 基础定义:
:root { --primary-color: #007bff; --bg-color: #fff; }<br>.dark { --primary-color: #222; --bg-color: #111; } - 切换方式二选一:
— 改class:document.documentElement.classList.toggle('dark')(推荐,语义清晰)
— 改data-theme:document.documentElement.setAttribute('data-theme', 'dark'),配合:root[data-theme="dark"]选择器 - 避免性能坑:不要在循环里频繁调用
style.setProperty('--color', xxx),批量更新优先用cssText或切换预设类名 - 持久化注意:
localStorage存的是主题标识(如'dark'),不是颜色值本身;恢复时应先设class,再让CSS变量自动生效
构建时注入变量 vs 运行时切换的本质区别
Webpack的less-loader的modifyVars只能生成多套独立CSS文件(如app-light.css/app-dark.css),和“动态切换”无关。它解决的是构建态主题定制,不是运行时响应。
- 如果你用
modifyVars但只生成一套CSS,那所有@xxx早已固化,JS再怎么操作class都无效 - 真正运行时切换的唯一路径:Less只负责把
@xxx转成var(--xxx),其余全部交给CSS变量机制 - 容易被忽略的细节:
@import顺序决定变量覆盖优先级,variables.less必须在所有样式文件之前@import,否则@color: var(--primary-color)可能找不到声明
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











