@keyframes 必须顶层声明,不可嵌套于选择器或mixin中;IE11需用0%/100%替代from/to;命名须静态或通过~"@{name}"拼接;推荐拆分mixin控制动画维度,避免覆盖。

@keyframes 必须顶层声明,Mixin 不能内嵌它
Less 编译器把 @keyframes 当作和 @import、@media 同级的顶层指令,一旦写进选择器、mixin 或媒体查询块里,就会直接报 ParseError: Unexpected token,或者静默丢弃整段规则——不是“不支持”,是语法层级错了。
常见错误包括:
-
.btn { @keyframes bounce { } }→ 嵌套在选择器内,编译失败 -
.animate(@name) { @keyframes @{name} { } }→ 变量插值 + 嵌套,名称不解析且语法非法
正确做法:所有 @keyframes 必须放在 .less 文件最外层(即没有任何 {} 包裹),名称用静态字符串,比如:
@keyframes slideIn {
from { transform: translateX(-100%); }
to { transform: translateX(0); }
}
IE11 兼容注意:from/to 不被识别,必须写成 0%/100%。
用 ~"@{name}" 实现“伪动态”命名,但需全局唯一
Less 不允许 @keyframes @{prefix}-slide 这类纯变量插值,但可以用字符串拼接 + 转义实现近似效果。关键不是运行时生成,而是确保编译后 CSS 名字合法、不冲突、可复用。
操作要点:
- 在文件顶部统一定义前缀变量:
@prefix: card; - 声明时用
~"@{prefix}-slide",调用时也用完全相同的表达式:animation: ~"@{prefix}-slide" 0.3s; - 避免前缀含空格、斜杠、括号等非法字符;大小写敏感,
CardSlide和cardslide算两个不同动画 - 多文件共用时,把所有
@keyframes集中到animations/_keyframes.less,用@import (once)引入
拆分 mixin 控制维度,别堆参数
把 animation-name、duration、fill-mode 全塞进一个 .animate(@name, @dur, @easing, @count) 里,极易传错顺序,后期改个时长还得重写整行。更糟的是,漏掉 animation-fill-mode: forwards 会导致动画一结束就回退到初始态——而 animation 简写默认不包含它。
推荐拆成独立 mixin:
.animate-name(@name) { animation-name: @name; }
.animate-time(@dur: 0.3s) { animation-duration: @dur; }
.animate-fill(@mode: forwards) { animation-fill-mode: @mode; }
单位要统一:全用 s 或全用 ms,300ms 和 0.3s 混用可能引发浏览器解析差异。
多个动画叠加靠 class 组合,不是 mixin 嵌套
Less 的 mixin 是文本替换,不是返回样式块的函数。写 .animate-scale().animate-glow().animate-border() 会覆盖而非叠加,最终只生效最后一个。
可行方式:
- 定义语义 class,如
.is-scaling、.has-glow、.border-pulsing,各自绑定不同@keyframes,HTML 里多 class 控制 - 若必须用逗号写法:
animation: scale-in 0.3s, glow 1s;,注意旧版 Safari 对多动画支持不稳定,生产环境建议 JS 动态切换 class 更可控 - 浏览器按 CSS 声明顺序覆盖,后写的
animation-name会覆盖前面的,除非用逗号明确并列
真正容易被忽略的点是:动画名必须静态、forwards 必须显式写、单位必须统一——这三处出错,不会报 Less 编译错误,但动画表现会完全失常,排查起来反而最耗时间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











