核心概念:理解 CSS 动画的两个主要方式

在开始之前,需要了解 CSS 中创建动画的两种主要方法,它们适用于不同的场景:

css animation 模板
(图片来源网络,侵删)
  1. transition (过渡):用于在状态改变时平滑地过渡效果,鼠标悬停 (hover)、点击 (active)、元素被添加或移除时,它更像是一个“反应式”的动画。
  2. @keyframes (关键帧动画):用于创建复杂、多步骤的动画序列,你可以定义动画在特定时间点(0%, 50%, 100%)的样式,浏览器会自动填充中间的过渡,它更像是一个“主动式”的、可以无限循环的动画。

transition (过渡) 模板

transition 是最简单、最常用的动画方式。

语法模板

/* 1. 定义初始状态(通常是元素的默认样式) */
.element {
  width: 100px;
  height: 100px;
  background-color: #3498db;
  /* 关键:指定哪些属性需要过渡,以及过渡的持续时间和效果 */
  transition: property duration timing-function delay;
}
/* 2. 定义最终状态(通常是伪类或类改变后的样式) */
.element:hover {
  width: 200px;
  background-color: #e74c3c;
  /* 注意:这里通常不写 transition,否则可能会产生不自然的反向过渡 */
}

参数详解

  • property: 指定应用过渡的 CSS 属性。
    • all: 所有属性都过渡(默认,但性能开销大)。
    • width, background-color, transform, opacity: 具体属性名。
    • none: 不过渡任何属性。
  • duration: 过渡持续的时间,单位可以是 s (秒) 或 ms (毫秒)。
  • timing-function: 过渡的速度曲线,决定动画的节奏感。
    • ease: 默认值,慢 -> 快 -> 慢。
    • linear: 匀速。
    • ease-in: 慢 -> 快。
    • ease-out: 快 -> 慢。
    • ease-in-out: 慢 -> 快 -> 慢 (与 ease 类似,但更明显)。
    • cubic-bezier(): 自定义贝塞尔曲线(高级用法)。
  • delay: 过渡的延迟时间,单位同 duration

实用模板示例

模板 1:悬停放大效果

<div class="card">Hover Me</div>
.card {
  width: 150px;
  height: 200px;
  background: linear-gradient(45deg, #6a11cb, #2575fc);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  cursor: pointer;
  /* 只对 transform 和 opacity 属性进行过渡,性能最佳 */
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
  transform: scale(1.05); /* 缩放 */
  box-shadow: 0 10px 20px rgba(0,0,0,0.2); /* 添加阴影 */
}

模板 2:淡入淡出

<div class="fade-box"></div>
.fade-box {
  width: 100px;
  height: 100px;
  background-color: #2ecc71;
  opacity: 1; /* 初始不透明 */
  transition: opacity 1s ease-in-out;
}
.fade-box.hidden {
  opacity: 0; /* 添加类后变为透明 */
}

@keyframes (关键帧动画) 模板

transition 无法满足需求时(例如需要循环、多个步骤、更复杂的路径),就需要使用 @keyframes

css animation 模板
(图片来源网络,侵删)

语法模板

/* 1. 定义关键帧动画 */
@keyframes animationName {
  0% {
    /* 动画开始时的样式 */
    transform: translateX(0);
    opacity: 1;
  }
  50% {
    /* 动画中途的样式 */
    transform: translateX(100px);
    opacity: 0.5;
  }
  100% {
    /* 动画结束时的样式 (与 0% 相同可实现循环) */
    transform: translateX(200px);
    opacity: 1;
  }
}
/* 2. 将动画应用到元素上 */
.animated-element {
  width: 50px;
  height: 50px;
  background-color: #f39c12;
  /* 应用动画 */
  animation-name: animationName;
  animation-duration: 2s; /* 动画一次持续的时间 */
  animation-timing-function: ease-in-out; /* 速度曲线 */
  animation-delay: 0.5s; /* 延迟开始 */
  animation-iteration-count: infinite; /* 播放次数: infinite 无限, 3 播放3次 */
  animation-direction: alternate; /* 播放方向: normal(正向), alternate(往返) */
  /* 简写属性 (推荐使用) */
  /* animation: name duration timing-function delay iteration-count direction; */
  animation: animationName 2s ease-in-out 0.5s infinite alternate;
}

参数详解

  • animation-name: 指定 @keyframes 的名称。
  • animation-duration: 同 transition
  • animation-timing-function: 同 transition
  • animation-delay: 同 transition
  • animation-iteration-count: 播放次数。
    • infinite: 无限循环。
    • 数字:具体次数。
  • animation-direction: 播放方向。
    • normal: 正向播放(默认)。
    • reverse: 反向播放。
    • alternate: 正向 -> 反向 -> 正向... 往返播放。
    • alternate-reverse: 反向 -> 正向 -> 反向... 往返播放。
  • animation-fill-mode: 动画结束后的状态。
    • none: 默认,动画结束后回到原始状态。
    • forwards: 动画结束后,保持最后一帧的样式。
    • backwards: 动画开始前,保持第一帧的样式(在 delay 期间生效)。
    • both: 同时应用 forwardsbackwards

实用模板示例

模板 1:加载旋转动画

<div class="loader"></div>
.loader {
  width: 40px;
  height: 40px;
  border: 5px solid #f3f3f3; /* 灰色背景 */
  border-top: 5px solid #3498db; /* 蓝色顶部 */
  border-radius: 50%;
  animation: spin 1s linear infinite; /* 无限循环匀速旋转 */
}
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

模板 2:弹跳进入动画

<div class="bounce-in">Bounce In!</div>
.bounce-in {
  width: 100px;
  height: 100px;
  background-color: #9b59b6;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  animation: bounceIn 0.8s ease-out;
}
@keyframes bounceIn {
  0% {
    transform: scale(0.1);
    opacity: 0;
  }
  60% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

模板 3:打字机效果

<div class="typewriter">Hello, CSS Animation!</div>
.typewriter {
  overflow: hidden; /* 隐藏超出部分 */
  border-right: .15em solid orange; /* 光标效果 */
  white-space: nowrap; /* 不换行 */
  margin: 0 auto;
  letter-spacing: .15em;
  animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite;
}
/* 打字动画 */
@keyframes typing {
  from { width: 0 }
  to { width: 100% }
}
/* 光标闪烁动画 */
@keyframes blink-caret {
  from, to { border-color: transparent }
  50% { border-color: orange; }
}

高级技巧与最佳实践

  1. 性能优化

    css animation 模板
    (图片来源网络,侵删)
    • 优先使用 transformopacity: 这两个属性由 GPU 加速,不会引起页面重排和重绘,性能最佳,避免对 width, height, margin, left 等属性进行动画。
    • 使用 will-change: 对于复杂的动画,可以在元素上提前告知浏览器 will-change: transform, opacity;,让浏览器提前做好准备,提升性能,但不要滥用,只在性能确实成为瓶颈时使用。
  2. 动画库

    • Animate.css: 一个非常流行的 CSS 动画库,提供大量开箱即用的动画效果,只需添加类名即可。
      <h1 class="animate__animated animate__bounce">An animated element</h1>
    • Magic Animations: 另一个有趣的动画库。
  3. JavaScript 控制

    • 可以通过 JavaScript 动态添加或移除类名来触发 CSS 动画。

      const element = document.querySelector('.my-element');
      element.classList.add('animate-pulse'); // 触发动画
      // 动画结束后移除类名(可选)
      element.addEventListener('animationend', () => {
        element.classList.remove('animate-pulse');
      });

快速参考速查表

功能 transition @keyframes
触发方式 状态改变 (hover, focus, 类变化等) 自动或通过JS触发
定义方式 直接在属性中定义 @keyframes 规则中定义
复杂度 简单(开始 -> 结束) 复杂(多个关键帧)
循环 只能执行一次(除非状态再次改变) 可以轻松设置无限循环
最佳场景 交互反馈、微交互 页面加载动画、循环动画、复杂序列

希望这份模板和指南能成为您开发 CSS 动画的强大工具!