返回首页

CSS3 动画有哪些?

问题解析

CSS3 动画让网页从静态变为动态,是提升用户体验的重要手段。面试考察这个问题,是想要了解候选人对 CSS 动画技术的全面掌握,包括过渡、变换和关键帧动画的使用和区别。

CSS 实现动画的三种方式

方式 特点 适用场景
Transition 简单过渡,需触发条件 状态变化(hover、focus 等)
Transform 视觉变换,性能好 位移、旋转、缩放等
Animation 复杂关键帧动画 循环、复杂路径动画

1. Transition 过渡动画

基本用法

.button {
  background: blue;
  transition: background 0.3s ease;
}

.button:hover {
  background: red;
}

完整属性

.element {
  /* 简写 */
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

  /* 详细 */
  transition-property: width, height, background-color;
  transition-duration: 0.3s;
  transition-timing-function: ease-in-out;
  transition-delay: 0.1s;
}

时间函数

/* 预设值 */
transition-timing-function: linear;       /* 匀速 */
transition-timing-function: ease;         /* 慢-快-慢(默认) */
transition-timing-function: ease-in;      /* 慢开始 */
transition-timing-function: ease-out;     /* 慢结束 */
transition-timing-function: ease-in-out;  /* 慢开始和结束 */
transition-timing-function: step(4);      /* 分步动画 */

/* 自定义贝塞尔曲线 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); /* 弹性效果 */

触发条件

Transition 需要状态变化才能触发:

/* 伪类触发 */
.element:hover { transform: scale(1.1); }
.element:focus { border-color: blue; }

/* 类切换 */
.element.active { opacity: 1; }

/* 属性变化(通过 JS) */
.element.style.width = '200px';

2. Transform 变换

Transform 常与 Transition/Animation 配合使用。

2D 变换

.element {
  /* 位移 */
  transform: translate(50px, 100px);     /* x, y */
  transform: translateX(50px);
  transform: translateY(100px);

  /* 缩放 */
  transform: scale(1.5);                 /* 等比缩放 */
  transform: scale(1.2, 0.8);            /* x, y 不等比 */
  transform: scaleX(-1);                 /* 水平翻转 */

  /* 旋转 */
  transform: rotate(45deg);
  transform: rotate(0.5turn);            /* 半圈 */

  /* 倾斜 */
  transform: skew(30deg, 10deg);

  /* 组合(从右向左执行) */
  transform: translateX(100px) rotate(45deg) scale(1.5);
}

3D 变换

.container {
  perspective: 1000px;                   /* 透视距离 */
  perspective-origin: center center;     /* 透视原点 */
}

.element {
  transform-style: preserve-3d;          /* 保持 3D */

  /* 3D 变换 */
  transform: translate3d(50px, 100px, 200px);
  transform: rotate3d(1, 1, 0, 45deg);   /* x, y, z轴 + 角度 */
  transform: rotateX(45deg);
  transform: rotateY(45deg);
  transform: scaleZ(2);

  /* 背面可见性 */
  backface-visibility: hidden;
}

变换原点

.element {
  transform-origin: center center;       /* 默认值 */
  transform-origin: top left;
  transform-origin: 100% 100%;
  transform-origin: 50px 50px;
}

3. Animation 关键帧动画

基本用法

@keyframes slideIn {
  from {
    transform: translateX(-100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

.element {
  animation: slideIn 0.5s ease-out forwards;
}

多关键帧动画

@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
    animation-timing-function: ease-out;
  }
  50% {
    transform: translateY(-20px);
    animation-timing-function: ease-in;
  }
}

@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.05); }
  100% { transform: scale(1); }
}

.element {
  animation: bounce 1s infinite;
}

完整属性

.element {
  /* 简写 */
  animation: slideIn 0.5s ease 0.1s 3 alternate forwards running;

  /* 详细 */
  animation-name: slideIn;              /* 动画名称 */
  animation-duration: 0.5s;             /* 持续时间 */
  animation-timing-function: ease;      /* 时间函数 */
  animation-delay: 0.1s;                /* 延迟 */
  animation-iteration-count: 3;         /* 播放次数(infinite 无限) */
  animation-direction: normal;          /* 播放方向 */
  animation-fill-mode: forwards;        /* 填充模式 */
  animation-play-state: running;        /* 播放状态 */
}

Animation 属性详解

属性 说明
direction normal/reverse/alternate/alternate-reverse 播放方向
fill-mode none/forwards/backwards/both 动画前后的样式
play-state running/paused 播放/暂停
/* 填充模式示例 */
.fade-in {
  opacity: 0;
  animation: fadeIn 1s forwards;  /* 保持结束状态 */
}

/* 播放状态控制 */
.paused:hover {
  animation-play-state: paused;
}

深入理解

性能优化

/* 触发 GPU 加速的属性 */
.optimized {
  will-change: transform, opacity;     /* 提示浏览器优化 */
  transform: translateZ(0);            /* 强制 GPU 加速 */
}

/* 避免触发重排的属性 */
/* 好的属性:transform, opacity */
/* 避免:width, height, top, left, margin, padding */

requestAnimationFrame vs CSS 动画

CSS 动画 JS 动画
性能好(浏览器优化) 控制更灵活
简单场景首选 复杂交互首选
脱离主线程 可以暂停/恢复

动画库选择

特点 适用场景
CSS 原生 性能好,无依赖 简单动画
Animate.css 预设动画丰富 快速实现
GSAP 功能强大,专业级 复杂时间线动画
Lottie 支持 AE 导出 复杂矢量动画
Framer Motion React 生态 React 项目

无障碍访问

/* 尊重用户的减少动画偏好 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

实用动画效果

常用工具类

/* 淡入淡出 */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes fadeOut {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* 缩放弹出 */
@keyframes popIn {
  0% { transform: scale(0); opacity: 0; }
  80% { transform: scale(1.1); }
  100% { transform: scale(1); opacity: 1; }
}

/* 摇晃 */
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
  20%, 40%, 60%, 80% { transform: translateX(5px); }
}

/* 旋转加载 */
@keyframes spin {
  to { transform: rotate(360deg); }
}

/* 脉冲 */
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* 滑动 */
@keyframes slideUp {
  from { transform: translateY(100%); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

使用示例

/* 加载动画 */
.loading {
  width: 40px;
  height: 40px;
  border: 3px solid #f3f3f3;
  border-top-color: #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

/* 提示动画 */
.toast {
  animation: slideUp 0.3s ease-out, fadeOut 0.3s ease-in 2.7s forwards;
}

/* 错误提示 */
.error-input {
  animation: shake 0.5s ease-in-out;
}

面试要点

  1. 能够区分 transition 和 animation 的适用场景
  2. 理解 transform 的性能优势和 GPU 加速原理
  3. 能够写出常用的关键帧动画
  4. 了解 will-change 和 transform: translateZ(0) 的作用
  5. 知道 prefers-reduced-motion 媒体查询的重要性
  6. 理解哪些属性会触发重排(reflow),哪些只会触发重绘(repaint)