Less变量需严格遵循编译期静态替换规则:命名须带语义前缀(如@btn-primary-bg)、禁用泛义名、末尾加分号;导入须按依赖顺序显式声明;主题切换必须配合CSS自定义属性(:root{--primary-color:@primary-color})实现运行时响应。

Less变量在主题系统里不是“写完就能换肤”,而是编译期静态替换,变量名冲突、作用域混乱、引入顺序错乱,三者任一出问题,@primary-color改了但按钮颜色纹丝不动就是常态。
变量命名必须带语义前缀,别碰@primary-color这种裸名
全局裸变量是主题系统崩溃的起点。Ant Design、Bootstrap 或你自己的 UI 库都可能定义同名 @primary-color,一旦 @import 顺序不对,后导入的直接覆盖前面的,且无任何警告。
- 改用模块+用途组合命名:
@btn-primary-bg、@card-header-border-color、@form-input-focus-shadow - 禁用泛义名:
@base、@text、@color1—— 编译后无法定位来源,调试时只能靠猜 - 所有变量声明末尾必须加分号:
@spacing-sm: 4px;漏掉分号会导致后续所有变量静默失效
变量文件必须按依赖顺序显式导入,index.less 是强制入口
主题系统里变量不是“全局可见”,而是严格遵循 @import 的文本顺序。指望“自动合并”或“就近查找”只会让 @theme-mode 在深色模式下完全不生效。
- 基础原子变量(颜色、间距、圆角)单独放在
variables/base.less - 组件级变量(如按钮尺寸、卡片阴影强度)放在
components/button/variables.less,且只引用base.less中的变量,不重新定义 - 每个目录下必须有
index.less,只做两件事:@import "variables"; @import "mixins"; @import "component"; - 根主题文件(如
themes/dark.less)只@import "../index";,绝不直接@import "components/button/button"
主题切换不能只靠变量,必须同步输出 CSS 自定义属性
仅靠 Less 变量无法让 JS 动态读取当前主题值,也无法支持运行时切换。变量编译完就消失了,留下的只是硬编码的 #1890ff。
立即学习“前端免费学习笔记(深入)”;
- 在
variables/base.less里,除了@primary-color: #1890ff;,还得加一句::root { --primary-color: @primary-color; } - 深色主题文件(
themes/dark.less)应覆盖 :root 下的自定义属性,而非只改 Less 变量::root { --primary-color: #52c418; --bg-base: #1f1f1f; } - JS 侧通过
getComputedStyle(document.documentElement).getPropertyValue('--primary-color')读取,确保与样式层一致
嵌套中别用变量覆盖主题变量,状态类应独立声明
在 .button { @primary-color: #ff6b35; background: @primary-color; } 这种写法里,局部 @primary-color 不会触发主题更新,反而切断了和全局变量的关联,导致主题切换失效。
- 组件内部禁止重定义主题变量,所有颜色/尺寸必须引用顶层变量
- 状态变体(如
.button--danger)用 mixin 封装,不靠嵌套内覆盖:.button--danger { background: @btn-danger-bg; color: @btn-danger-color; } - 伪类状态(
&:hover)必须用darken()或lighten()基于原始变量计算,而不是写死新值
最易被忽略的一点:变量不是主题系统的全部。它只负责编译期静态替换;真正实现运行时响应、跨技术栈(JS/CSS/React)同步、无障碍对比度适配,必须靠 --custom-property 承接,而 Less 只是把它们可靠地生成出来。漏掉这层映射,所谓“一键换肤”永远停留在改完变量要重新编译的阶段。


















