一、先搞清楚它们的基本舞步

(技术栈:原生CSS)

当我们打开网页时的各种流畅效果,要么像呼吸般自然(过渡),要么像编排好的舞蹈(动画)。这两个技术本质上都在操作时间轴,但发力方式截然不同。

1.1 过渡的本质特征

/* 按钮悬停变色过渡 */
.button {
  background: #3498db;
  transition: all 0.3s ease-out; /* 声明监听的属性和时间 */
}

.button:hover {
  background: #e74c3c;
  transform: translateY(-3px); /* 这里的变化会被过渡接管 */
}

这个最常见的例子就像开关灯时的渐亮效果,过渡只关注变化的过程。注意要设置初始状态和目标状态两个关键帧,浏览器自动计算中间值。

1.2 动画的编排艺术

/* 加载旋转动画 */
@keyframes spin {
  0% {
    transform: rotate(0deg);
    opacity: 0.5;
  }
  50% {
    opacity: 1; /* 中途的额外状态 */
  }
  100% {
    transform: rotate(360deg);
    opacity: 0.5;
  }
}

.loader {
  animation: spin 2s infinite linear; /* 明确的时间轴控制 */
}

这里动画定义了完整的时间线,就像导演把控每个镜头的细节。通过关键帧百分比精确控制元素在各时间点的状态,适合复杂的多阶段动态效果。

二、使用场景的黄金分割线

(技术栈:原生CSS)

2.1 无脑选过渡的情况

/* 导航栏折叠效果 */
.nav-collapse {
  max-height: 0;
  transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.active .nav-collapse {
  max-height: 500px; /* 自动计算的高度过渡 */
}

这里非常适合过渡的场景:触发条件明确(类名切换)、状态切换简单(高度变化)。如果用动画反而需要计算具体高度,不符合"自动补间"的需求。

2.2 必须动用动画的情形

/* 轮播图入场效果 */
@keyframes slideIn {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

.new-slide {
  animation: slideIn 0.6s both; /* 独立的入场时间线 */
}

轮播元素的入场需要精确控制初始状态(从右侧滑入),这时候动画的关键帧控制就比单纯的过渡更加灵活,特别是在需要叠加多个属性的场景。

三、浏览器眼里的性能账单

(技术栈:现代浏览器渲染机制)

3.1 硬件加速的奥妙

/* 高性能位移动画 */
@keyframes move {
  to { transform: translate3d(100px,0,0); }
}

.box {
  will-change: transform; /* 预通知浏览器变化 */
  animation: move 1s;
}

使用transform和opacity这些合成层属性,配合will-change声明,可以触发GPU加速。注意过渡同样可以享受这个优化。

3.2 高频触发的陷阱

/* 错误的高频率更新示例 */
.box {
  transition: left 0.3s;
}

/* 脚本不断修改left值 */
element.style.left = x + 'px';

此时频繁修改left属性会导致持续的重排(reflow),改用transform: translateX()则只会引起合成(composite),性能差异可能达到十倍量级。

四、那些年我们踩过的坑

(技术栈:CSS与JavaScript配合)

4.1 状态同步的幽灵

// 动画结束后执行回调
element.addEventListener('animationend', () => {
  console.log('可以安全操作DOM了');
});

// 错误做法示例
element.style.animation = 'slide 1s';
doSomething(); // 这时候动画可能还没开始

动画的异步特性需要用事件监听来控制流程,而过渡可以通过transitionend事件达成类似效果,但要注意跨浏览器兼容性。

4.2 媒体查询里的意外

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
}

无障碍需求强制要求必须处理运动偏好设置,突然移除动画可能导致元素状态异常,好的做法是提供替代的样式方案。

五、抉择的艺术:五项核心评判标准

  1. 用户意图的映射
    导航菜单展开对应"自然过渡",新功能提示适合"强调动画"

  2. 状态复杂度
    当需要在运动轨迹中设置多个检查点时(比如先加速后减速),必然选择动画

  3. 交互反馈响应
    按钮点击涟漪效果用过渡更直接,无需完整时间线控制

  4. 系统资源占用
    移动端页面滚动时的视差效果应当采用硬件加速的transform动画

  5. 可维护性考量
    交互动画集中的场景适合使用CSS动画统一管理时间轴参数