用 Sass @mixin 封装 transition 可控管理页面转场:分层定义基础、属性级、场景化(如 scale-fade)过渡,配合状态类与 :is() 动态启用,兼顾性能(will-change)、兼容性(条件前缀)和可维护性。

为什么直接写 transition 容易失控
页面转场动画一旦涉及多个组件、不同触发条件(比如路由切换、模态框显隐、折叠面板展开),硬编码 transition 会迅速变成维护噩梦:重复写 transition: all 0.3s ease,改一个时长要搜全项目,加个新属性漏了 transform 导致闪动,甚至因为没加 will-change 触发不了硬件加速——这些都不是“写不出来”,而是“改不动”。
用 Sass 的 @mixin 封装过渡逻辑,核心不是炫技,是把“什么时候动、动什么、怎么动”这三个变量收口到一处。
定义可组合的 transition Mixin
别只做一个 transition-all。实际项目里需要分层控制:
-
@mixin transition-base($duration: 0.3s, $easing: ease) { transition: all $duration $easing; }—— 基础兜底,但慎用 -
@mixin transition-props($props: (opacity, transform), $duration: 0.25s, $easing: cubic-bezier(0.4, 0, 0.2, 1)) { transition: $props $duration $easing; }—— 明确指定属性,避免意外触发重排 -
@mixin transition-scale-fade($duration: 0.3s) { transition: transform $duration, opacity $duration; will-change: transform, opacity; }—— 针对缩放+淡入/出场景预设,自动加will-change
关键点:参数默认值要符合项目主视觉节奏;$props 用列表传入,比拼字符串更安全;will-change 不写进基础 mixin,只在明确需要性能优化的场景显式启用。
立即学习“前端免费学习笔记(深入)”;
配合 :is() 和状态类做动态过渡开关
Sass mixin 只管声明,真正生效得靠 CSS 选择器匹配。别在每个组件里写 .card--enter { @include transition-scale-fade; },而是统一用状态类 + 属性选择器:
.page-transition-enter,
.page-transition-leave-to,
.modal--open,
.accordion--expanded {
@include transition-scale-fade;
}
<p>/<em> 进入中、离开中状态禁用过渡,避免二次触发 </em>/
.page-transition-enter-active,
.page-transition-leave-active {
transition: none;
}
这样 JS 只需增删 page-transition-enter 这类语义类名,Sass 负责把过渡规则“按需注入”。注意 transition: none 必须加在 -active 类里,否则 Vue/React 的 enter/leave 钩子会和 CSS 过渡抢帧。
Mixin 里处理浏览器前缀和兼容性降级
现代 CSS 已不需要手动写 -webkit-transition,但某些老项目仍需支持 iOS 12 或 Android 4.4。这时 mixin 可内置降级逻辑:
- 用
@if判断是否启用前缀:@if $legacy-support == true { -webkit-transition: ...; } - 对
transform相关过渡,单独封装@mixin transition-transform($duration),内部自动补-webkit-transform - 避免在 mixin 中写
transition: all—— 它在 Safari 旧版中会忽略will-change,导致动画卡顿
真正麻烦的不是写法,是当设计师临时要求“这个弹窗入场快一点,但退出慢一点”,你得立刻判断该改 mixin 参数、加新 class,还是拆成两个独立 mixin —— 这种决策没法自动化,只能靠一开始把常见转场模式(fade / slide / scale / flip)都抽成独立 mixin 留好扩展口。


















