less 会生成重复的 @keyframes 名称,是因为每次调用含 @keyframes 的 mixin 都会原样展开关键帧块;且 @keyframes 必须位于顶层、名称静态,不可嵌套或变量插值。

为什么 Less 会生成重复的 @keyframes 名称?
Less 是静态编译器,每次调用含 @keyframes 的 mixin,都会原样展开一次该关键帧块。比如你在两个组件里都用了 .animate-fade-in(),且它内部写了 @keyframes fade-in { ... },最终 CSS 就会出现两段完全相同的 @keyframes fade-in 声明——浏览器只认第一个,后一个被忽略,但体积变大、维护混乱。
更隐蔽的问题是:若 mixin 里用了变量拼接名称(如 @keyframes @{prefix}-fade),Less 无法解析,直接报 ParseError: Unexpected token 或静默丢弃整块。
必须把 @keyframes 提到顶层且名称静态
所有 @keyframes 规则只能出现在 .less 文件最外层,不能嵌套在选择器、mixin 或媒体查询内。名称必须是纯字符串,不能依赖变量运算。
- ✅ 正确:
@keyframes bounce-in { from { transform: scale(0.8); } to { transform: scale(1); } } - ❌ 错误:
.btn { @keyframes btn-bounce { ... } }(嵌套 → 编译失败) - ❌ 错误:
@keyframes @{name}-in { ... }(变量插值 → 不识别) - ⚠️ 可行但需谨慎:
@keyframes ~"@{prefix}-bounce",前提是@prefix已在文件顶部定义为字符串,且全局唯一
用 Mixin 封装调用,而不是封装定义
动画逻辑复用靠「声明分离 + 调用组合」:关键帧集中定义,mixin 只负责设置 animation 相关属性。这样既避免重复生成,又支持差异化控制。
- 把所有
@keyframes收拢到animations/_keyframes.less,用@import (once)引入主文件 - 写一个轻量 mixin,例如
.use-animation(@name, @dur: 0.3s, @easing: ease) { animation: @name @dur @easing forwards; } - 调用时显式传参:
.card { .use-animation(bounce-in, 0.4s); }、.modal { .use-animation(bounce-in, 0.2s, cubic-bezier(0.2, 0.8, 0.4, 1)); } - 务必补上
forwards——animation简写不包含animation-fill-mode,漏掉会导致动画结束瞬间回退
多组件需要不同前缀时怎么安全拼接?
当多个模块要各自拥有语义化动画名(如 card-bounce、input-pulse),又不想手写一堆重复 @keyframes,就得靠 ~"" 字符串转义 + 严格作用域控制。
- 在组件级 .less 文件顶部定义前缀:
@prefix: card; - 声明关键帧:
@keyframes ~"@{prefix}-bounce" { from { transform: scale(0.95); } to { transform: scale(1); } } - 调用动画:
animation: ~"@{prefix}-bounce" 0.3s ease-out forwards; - ⚠️ 关键约束:前缀变量必须在声明和调用处处于同一作用域;不能是函数参数传入;不能含空格或特殊字符(否则
~""也救不了)
from/to,必须用 0%/100%;而 ~"@{prefix}-bounce" 拼出的名字大小写敏感,animation: ~"card-bounce" 和 @keyframes CardBounce 完全不匹配。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











