Less变量无法在运行时修改,因其在构建阶段已被编译为固定值,运行时不存在;须用@primary-color: var(--primary-color, #007bff)桥接CSS变量,并通过document.documentElement.style.setProperty()动态更新。

Less变量无法在运行时改变CSS样式,是因为它压根不会出现在运行时——所有@primary-color类的变量都在构建阶段被替换成固定值,浏览器加载的只是纯CSS,连变量名都不存在。
Less变量在编译期就被“蒸干”了
你写的@primary-color: #007bff;,经过lessc或less-loader处理后,直接变成color: #007bff;。最终输出的CSS文件里没有@primary-color,也没有任何可被JS读取或修改的痕迹。
常见错误现象:
- 在开发者工具里搜索
@primary-color,结果为空——它早被删光了 - 写
.dark { @primary-color: #222; },编译器要么忽略,要么报variable is undefined - 调用
less.modifyVars({ '@primary-color': '#ff6b35' }),只对尚未编译的源码生效;已生成的CSS不会重绘,页面无变化
想让JS控制颜色,必须用CSS变量桥接
关键不是“怎么改Less变量”,而是“怎么绕过Less,让JS直接驱动样式”。正确做法是让Less放弃固化值,转而依赖CSS变量的运行时求值能力:
- 在全局作用域(如
variables.less顶部)写:@primary-color: var(--primary-color, #007bff); -
var()的fallback(#007bff)不能省:未设置--primary-color时,可能退成transparent导致文字消失 - JS修改只需一行:
document.documentElement.style.setProperty('--primary-color', '#ff6b35'); - 切换主题时无需重载样式表,也不依赖
less.modifyVars或Webpack配置
别指望@{name}拼出var(--@{name})
@name: primary-color; → color: var(--@{name});看似能编译出color: var(--primary-color);,但这是字符串拼接,不是动态解析。
- 如果
@name来自函数计算(如extract()),Less 4.0+ 不支持运行时求值,插值失败 -
var(--@{name})在浏览器里会被当成无效语法丢弃,因为--@{name}不是合法的自定义属性名 - 安全写法永远是显式写死:
color: var(--primary-color, #007bff);
Ant Design或Umi项目中变量不生效的根源
Ant Design 3.x 默认引入的是编译好的antd.css,不是antd.less。你改modifyVars,等于对着空气调音。
- Webpack配置
lessOptions.modifyVars只影响antd.less的编译过程;若项目实际加载的是预编译CSS,则完全无效 - Umi项目需确认是否启用了
theme配置,并检查config.ts中cssLoaderOptions和lessLoaderOptions是否协同生效 - Vue/React单文件组件中的
<style lang="less"></style>是独立作用域,不会自动继承variables.less里的变量,必须显式@import
最容易被忽略的是:CSS变量一旦设在:root,就全局可见,多个组件可能意外覆盖同一变量;而Less变量根本不存在于运行时,谈不上“作用域泄漏”,但它的编译顺序和导入位置,会静默决定哪些样式用到了哪个值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











