变量需分层管理:variables.less仅纯声明编译期值,:root定义运行时css变量,通过主题map和each()生成多主题,组件变量限作用域,杜绝混用与全局污染。

直接结论:变量不是太多,而是没分层——把设计 Token、主题配置、运行时桥接混在一块,必然失控。真正要做的,是用 variables.less 管编译期值,用 :root 变量管运行时切换,两者桥接但绝不混写。
variables.less 只能声明,不能计算也不能嵌套
很多人在 variables.less 里写 @color-primary-light: lighten(@color-brand-primary, 10%),结果换深色模式时完全失效——因为 @color-brand-primary 已被设为 var(--primary-color, #1677ff),lighten() 拿到的是字符串 "var(--primary-color, #1677ff)",直接报错。
-
variables.less必须纯声明:只含@color-brand-primary: #1677ff;这类语义化赋值,结尾带分号 - 所有颜色派生(
lighten/darken)、间距倍数(@spacing-md: unit(@spacing-base * 4, px))必须基于原始色值/基础步长计算,再单独导出为 CSS 变量 - 禁止在变量里引用其他变量:
@primary-color: @blue;是高危操作,一旦@blue拼错或未定义,输出color: @blue;,浏览器直接丢弃整条规则
多主题必须靠 :root[data-theme] + each() 生成,别手写 light/dark.less
手写两套 light-vars.less 和 dark-vars.less 看似清晰,实则维护成本爆炸——新增一个 --radius-card,就得同步改两处;某天设计师说“暗色模式的边框要再浅一档”,你得翻两个文件找对应行。
- 统一用
@themes: { 'light': (#ffffff, #333333), 'dark': (#121212, #e0e0e0) };定义主题 Map - 用
each(@themes, .theme-loop);循环生成:root[data-theme='light']和:root[data-theme='dark']块 - 每个块内只写
--color-bg: ~"@{value[0]}";这类字符串插值,不调用 Less 函数 - JS 切换时只需
document.documentElement.setAttribute('data-theme', 'dark'),CSS 层级天然隔离,无闪烁、无伪类丢失
组件专属变量必须限制作用域,别往 :root 堆
看到项目里满屏 --btn-padding、--card-shadow 都挂在 :root?这是把组件实现细节暴露成全局契约——哪天想给某个页面的按钮加个特殊内边距,就只能靠 !important 覆盖,或者重写整套变量。
- 基础设计 Token(颜色、字号、圆角步长)放
:root,命名带语义前缀:--color-surface、--radius-sm - 组件专属变量(如
--card-padding、--modal-z-index)必须写在组件选择器内:.card { --card-padding: 16px; } - 这样既保证复用性(同个
.card类在任何上下文都用同一套内边距),又避免污染全局命名空间 - 检查是否乱堆:Chrome DevTools 的 Styles 面板里点
:root,如果超过 30 行且含大量-btn-、-input-前缀,就是警报信号
最常被忽略的一点:Less 变量和 CSS 变量根本不在一个维度上。前者是构建期文本替换,后者是运行时样式引擎读取的对象。试图用 Less 解决运行时问题(比如点击切换主题),就像用螺丝刀拧灯泡——工具错了,再使劲也没用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











