Skip to content
On this page

CSS 过渡与动画

CSS 过渡和动画用于创建平滑的视觉效果和动态交互。

概述

过渡和动画是现代网页设计中不可或缺的元素,它们能够提升用户体验和界面的动态效果。

过渡 (Transitions)

transition-property

指定要过渡的属性:

css
.element {
  transition-property: background-color; /* 单个属性 */
  transition-property: background-color, color, width; /* 多个属性 */
  transition-property: all; /* 所有可动画属性 */
}

transition-duration

设置过渡持续时间:

css
.element {
  transition-duration: 0.3s; /* 秒 */
  transition-duration: 300ms; /* 毫秒 */
  transition-duration: 0.5s, 1s; /* 多个属性的不同持续时间 */
}

transition-timing-function

设置过渡的时间函数:

css
.element {
  transition-timing-function: ease; /* 默认,慢-快-慢 */
  transition-timing-function: linear; /* 匀速 */
  transition-timing-function: ease-in; /* 慢开始 */
  transition-timing-function: ease-out; /* 慢结束 */
  transition-timing-function: ease-in-out; /* 慢开始和结束 */
  transition-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1); /* 自定义贝塞尔曲线 */
}

transition-delay

设置过渡延迟时间:

css
.element {
  transition-delay: 0.2s; /* 延迟0.2秒后开始过渡 */
}

transition 简写属性

css
.element {
  transition: background-color 0.3s ease 0.1s; /* property duration timing-function delay */
  transition: all 0.5s ease-in-out; /* 所有属性 */
  transition: width 0.3s ease, height 0.5s ease; /* 多个属性 */
}

动画 (Animations)

@keyframes 规则

定义动画的关键帧:

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

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}

animation-name

指定动画名称:

css
.element {
  animation-name: slideIn;
}

animation-duration

设置动画持续时间:

css
.element {
  animation-duration: 2s;
}

animation-timing-function

设置动画的时间函数:

css
.element {
  animation-timing-function: ease;
  animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1.0);
}

animation-delay

设置动画延迟:

css
.element {
  animation-delay: 0.5s;
}

animation-iteration-count

设置动画播放次数:

css
.element {
  animation-iteration-count: 1; /* 默认值 */
  animation-iteration-count: infinite; /* 无限循环 */
  animation-iteration-count: 3; /* 播放3次 */
}

animation-direction

设置动画方向:

css
.element {
  animation-direction: normal; /* 正向 */
  animation-direction: reverse; /* 反向 */
  animation-direction: alternate; /* 交替(正向-反向-正向...) */
  animation-direction: alternate-reverse; /* 反向交替 */
}

animation-fill-mode

设置动画之外的状态:

css
.element {
  animation-fill-mode: none; /* 默认 */
  animation-fill-mode: forwards; /* 保持最后状态 */
  animation-fill-mode: backwards; /* 保持初始状态 */
  animation-fill-mode: both; /* 同时应用 forwards 和 backwards */
}

animation-play-state

控制动画播放状态:

css
.element {
  animation-play-state: running; /* 运行(默认) */
  animation-play-state: paused; /* 暂停 */
}

.element:hover {
  animation-play-state: paused;
}

animation 简写属性

css
.element {
  animation: slideIn 2s ease-in-out 0.5s infinite alternate both;
  /* name duration timing-function delay iteration-count direction fill-mode */
}

常用动画效果

淡入淡出

css
.fade-in {
  animation: fadeIn 0.5s ease-in-out;
}

.fade-out {
  animation: fadeOut 0.5s ease-in-out;
}

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

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

滑动效果

css
.slide-up {
  animation: slideUp 0.3s ease-out;
}

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

旋转效果

css
.spinner {
  animation: spin 1s linear infinite;
}

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

脉冲效果

css
.pulse {
  animation: pulse 2s infinite;
}

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

性能优化

使用 transform 和 opacity

css
/* 推荐:这些属性不会触发重排 */
.smooth-transition {
  transition: transform 0.3s, opacity 0.3s;
}

.smooth-transition:hover {
  transform: scale(1.1);
  opacity: 0.8;
}

/* 避免:这些属性会触发重排和重绘 */
.bad-transition {
  transition: width 0.3s, height 0.3s, margin 0.3s;
}

使用 will-change 属性

css
.element {
  will-change: transform; /* 提示浏览器优化 */
}

使用 requestAnimationFrame

在 JavaScript 中配合使用:

javascript
// 在动画开始前提示浏览器
element.style.willChange = 'transform';

// 动画结束后移除提示
element.addEventListener('animationend', () => {
  element.style.willChange = 'auto';
});

高级动画技术

精灵动画 (Sprite Animation)

css
.sprite-animation {
  width: 100px;
  height: 100px;
  background-image: url('sprite.png');
  background-size: 400px 100px; /* 4帧,每帧100x100 */
  animation: sprite 1s steps(4) infinite;
}

@keyframes sprite {
  0% { background-position: 0 0; }
  100% { background-position: -400px 0; }
}

路径动画

css
.path-animation {
  offset-path: path('M0,0 C50,50 100,0 200,0');
  animation: followPath 2s linear infinite;
}

@keyframes followPath {
  0% { offset-distance: 0%; }
  100% { offset-distance: 100%; }
}

实用技巧

动画结束后的状态

css
.animation-keep-state {
  animation: myAnimation 1s forwards; /* 保持最终状态 */
}

条件动画

css
.element {
  transition: transform 0.3s ease;
}

.element.active {
  transform: translateX(100px);
}

动画队列

css
.element {
  animation: 
    fade 0.5s ease-in,
    slide 0.5s ease-out 0.5s,
    scale 0.3s ease 1s;
}

可访问性考虑

减少动画偏好

css
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

焦点动画

css
.focus-indicator {
  transition: box-shadow 0.2s ease;
}

.focus-indicator:focus {
  box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.5);
}

浏览器兼容性

渐进增强的动画

css
.progressive-animation {
  /* 基础样式 */
  opacity: 1;
}

@supports (animation: name 1s) {
  .progressive-animation {
    /* 动画增强 */
    animation: enhanceEffect 0.5s ease-in-out;
  }
}

最佳实践

  • 优先使用 transform 和 opacity 以获得最佳性能
  • 为动画提供清晰的开始和结束状态
  • 考虑用户的动画偏好设置
  • 避免过度使用动画,以免分散用户注意力
  • 确保动画有明确的目的和功能
  • 测试动画在不同设备上的性能表现
  • 为关键动画提供备选方案