可复用动画片段需将@keyframes声明于顶层且名称静态,通过mixin封装animation参数并显式设置animation-fill-mode: forwards;禁止在mixin内声明@keyframes,多文件共用时应集中定义并@import引入。

怎样用 animation 和 @keyframes 定义可复用的动画片段?
Less 本身不支持运行时生成 @keyframes,但可以用 mixin 封装参数化定义。关键在于把动画名、持续时间、缓动、方向等作为参数传入,再动态拼出唯一 @keyframes 名称,避免命名冲突。
- 动画名必须用字符串拼接(如
@{name}-fade-in),不能直接写死,否则多个调用会覆盖 -
@keyframes必须声明在顶层作用域,不能嵌套在 selector 或其他 mixin 内,否则编译失败 - 持续时间建议用变量传入(如
@duration: 0.3s),避免硬编码;单位必须带(0.3s≠0.3) - 示例:
.animate-fade-in(@duration: 0.3s, @easing: ease-out) { @keyframes fade-in-@{duration}-@{easing} { from { opacity: 0; } to { opacity: 1; } } animation: fade-in-@{duration}-@{easing} @duration @easing; }
如何让同一个 mixin 支持多种动画类型(淡入、滑入、缩放)?
靠参数区分行为,而不是写一堆独立 mixin。用 @type 控制关键帧逻辑,配合 guard 判断,比用多个 mixin 更易维护。
-
@type建议限定为几个字符串值(fade/slide-up/scale),避免自由输入导致逻辑失控 - guard 条件必须覆盖所有分支,漏掉
default()会导致编译时报错“no matching definition” - transform 动画需注意浏览器前缀兼容性,
translateY在旧版 Safari 中可能需要-webkit-transform - 示例:
.animate(@type, @duration: 0.3s, @easing: ease-out) when (@type = fade) { @keyframes animate-fade-@{duration} { from { opacity: 0; } to { opacity: 1; } } animation: animate-fade-@{duration} @duration @easing; } .animate(@type, @duration, @easing) when (@type = slide-up) { @keyframes animate-slide-up-@{duration} { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } animation: animate-slide-up-@{duration} @duration @easing; }
为什么直接在 class 中调用 mixin 会导致 @keyframes 重复生成?
Less 是静态编译,每次调用 mixin 都会重新展开其内部的 @keyframes 块。如果多个 class 都用了 .animate(fade),就会输出多份相同的 @keyframes animate-fade-0.3s,浪费 CSS 体积且可能被浏览器忽略后一份。
- 解决办法是把
@keyframes提前单独定义(不包在 mixin 里),mixin 只负责应用animation属性 - 或者用「一次性注册」模式:用全局变量
@_registered-animations记录已生成的动画名,guard 判断后再决定是否输出@keyframes - 更稳妥的做法是拆成两部分:一个
.register-animation()(只执行一次),一个.use-animation()(纯属性应用)
怎样让动画库支持暂停、反向、填充模式等进阶控制?
这些都属于 animation 复合属性的子项,不能靠单一 mixin 参数全覆盖。建议拆出独立的控制 mixin,按需组合。
立即学习“前端免费学习笔记(深入)”;
-
animation-play-state、animation-direction、animation-fill-mode应作为可选参数,不参与@keyframes生成逻辑 -
animation-fill-mode: forwards很容易被忽略,但对淡入类动画至关重要,否则元素会瞬间回退到初始状态 - 不要试图用一个大 mixin 涵盖全部 8 个
animation-属性,按使用频率分组更可控(比如.anim-pause、.anim-forwards) - 示例:
.anim-forwards() { animation-fill-mode: forwards; } .anim-reverse() { animation-direction: reverse; }
实际项目里,最常被漏掉的是 forwards 和 ease 的显式声明——浏览器默认值在不同场景下表现不一致,尤其是和 JS 交互时。动画库的价值不在炫技,而在消除这些隐式假设。


















