Skip to content

CSS 动画基础 ​

是什么 ​

CSS 做动画只有两个工具:transition(过渡) 和 animation(关键帧动画)。分清「什么时候用哪个」,动效就学会了一半。

transition vs animation ​

transitionanimation
触发方式状态变化时(hover、class 切换)自动播放,或 class 挂上就播
能否循环❌✅(infinite)
中间状态数只有起点和终点任意多个关键帧
典型用途hover、展开收起、颜色变化加载动画、入场、循环呼吸

一句话:状态 A ↔ B 用 transition,讲故事/循环用 animation。

性能铁律:只动 transform 和 opacity ​

浏览器渲染流水线里,transform 和 opacity 由合成器单独处理,不触发重排重绘;width、top、margin 每帧都要重新计算布局,掉帧元凶。

css
/* ❌ 动 margin:触发重排 */
.bad { transition: margin-left 300ms; }
.bad:hover { margin-left: 8px; }

/* ✅ 动 transform:不触发重排 */
.good { transition: transform 300ms; }
.good:hover { transform: translateX(8px); }

/* ✅ 淡入:opacity + 位移组合 */
.fade-in { animation: fade-in 300ms ease-out both; }
@keyframes fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

五个高频模板 ​

1. 按钮 hover(反馈) ​

css
.btn {
  transition: transform 150ms ease-out, box-shadow 150ms ease-out;
}
.btn:hover  { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,.12); }
.btn:active { transform: translateY(0) scale(.97); } /* 按压回弹感 */

2. 卡片入场(本站在用) ​

css
.card { animation: rise 500ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.card:nth-child(2) { animation-delay: 60ms; } /* 多张卡错峰:依次加 delay */
@keyframes rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

3. 加载 spinner(循环) ​

css
.spinner {
  width: 20px; height: 20px;
  border: 2px solid rgba(96, 144, 184, .25);
  border-top-color: #6090b8;
  border-radius: 50%;
  animation: spin 800ms linear infinite; /* 循环动画才用 linear */
}
@keyframes spin { to { transform: rotate(360deg); } }

4. 骨架屏微光(循环) ​

css
.skeleton {
  background: linear-gradient(90deg, #eee 25%, #f5f5f5 50%, #eee 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease infinite;
}
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

5. 折叠展开(高度不确定时) ​

css
.collapse { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 300ms ease-out; }
.collapse.open { grid-template-rows: 1fr; }
.collapse > div { overflow: hidden; }

不需要知道内容高度就能做高度动画——grid-template-rows: 0fr → 1fr 的技巧。

注意事项 ​

三个坑

  1. will-change: transform 是性能优化里最后一张牌:只加在确实卡顿的元素上,用完移除,全站乱加反而吃内存
  2. animation 的 both 填充模式让元素在 delay 期间保持第一帧——错峰入场必须加,否则卡片会先闪现再消失再入场
  3. 循环动画幅度要小(透明度 ±5%、位移 ±2px),大幅循环动画是注意力黑洞

更多现成片段收在微交互清单。