CSS动画与过渡

CSS过渡 (Transitions)

CSS过渡允许属性值在一定时间内平滑地变化,而不是瞬间改变。

属性 描述
transition-property 指定应用过渡的CSS属性 all 或具体属性名如 width, opacity
transition-duration 过渡持续时间 时间值如 0.3s500ms
transition-timing-function 过渡速度曲线 ease, linear, ease-in, ease-out, ease-in-out, cubic-bezier()
transition-delay 过渡开始前的延迟时间 时间值如 0.2s

过渡简写

css
transition: property duration timing-function delay;

示例代码

css
/* 基础过渡效果 */
.box {
  width: 100px;
  height: 100px;
  background: blue;
  transition: all 0.3s ease;
}

.box:hover {
  width: 200px;
  background: red;
}

/* 多属性不同过渡效果 */
.button {
  padding: 10px 20px;
  background: #4CAF50;
  color: white;
  transition: 
    background 0.4s ease-out,
    transform 0.2s ease-in;
}

.button:hover {
  background: #45a049;
  transform: scale(1.05);
}

CSS动画 (Animations)

CSS动画比过渡更强大,可以定义关键帧和更复杂的动画序列。

关键帧动画

css
@keyframes animation-name {
  0% { /* 起始状态 */ }
  50% { /* 中间状态 */ }
  100% { /* 结束状态 */ }
}

动画属性

属性 描述
animation-name 指定@keyframes动画名称 自定义名称
animation-duration 动画持续时间 时间值
animation-timing-function 动画速度曲线 同transition
animation-delay 动画开始前的延迟 时间值
animation-iteration-count 动画播放次数 数字或 infinite
animation-direction 动画播放方向 normal, reverse, alternate, alternate-reverse
animation-fill-mode 动画前后如何应用样式 none, forwards, backwards, both
animation-play-state 动画播放状态 running, paused

动画简写

css
animation: name duration timing-function delay iteration-count direction fill-mode;

示例代码

css
/* 跳动动画 */
@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-20px);
  }
}

.ball {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: red;
  animation: bounce 1s ease infinite;
}

/* 渐显动画 */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.element {
  animation: fadeIn 2s ease-out forwards;
}

/* 复杂动画 */
@keyframes slideAndRotate {
  0% {
    transform: translateX(0) rotate(0deg);
  }
  50% {
    transform: translateX(200px) rotate(180deg);
  }
  100% {
    transform: translateX(0) rotate(360deg);
  }
}

.box {
  animation: slideAndRotate 3s ease-in-out infinite;
}

性能优化建议

  1. 优先使用transform和opacity:这些属性不会触发重排,动画性能更好
  2. 避免动画过多:限制同时进行的动画数量
  3. 使用will-change:提前告知浏览器哪些属性会变化
  4. 减少动画范围:尽量在小区域使用动画
css
.optimized {
  will-change: transform, opacity;
  transform: translateZ(0); /* 有时可以触发硬件加速 */
}

实用技巧

悬停效果

css
.card {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}

加载动画

css
@keyframes spin {
  to { transform: rotate(360deg); }
}

.loader {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(0,0,0,0.1);
  border-radius: 50%;
  border-top-color: #09f;
  animation: spin 1s linear infinite;
}

步骤指示器

css
@keyframes progress {
  from { width: 0 }
  to { width: 100% }
}

.progress-bar {
  height: 4px;
  background: #ddd;
}

.progress-bar::after {
  content: '';
  display: block;
  height: 100%;
  background: #09f;
  animation: progress 2s ease-out forwards;
}

响应式动画

结合媒体查询创建适应不同屏幕的动画:

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

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

@media (max-width: 768px) {
  .element {
    animation: slideIn 0.5s ease-out;
  }
}

注意事项

  1. 优雅降级:确保没有动画时内容仍然可用
  2. 减少运动:为偏好减少运动的用户提供选项
  3. 浏览器前缀:某些旧浏览器需要前缀
  4. 测试性能:特别是在移动设备上
css
/* 减少运动偏好 */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}