CSS 动效基础

7.1 CSS 动效基础

CSS 动效是前端交互反馈与视觉体验的核心实现方式,基于浏览器合成线程原生渲染,具备 GPU 加速能力,性能远优于 JavaScript 动画。CSS 动效体系分为过渡动画与关键帧动画两大核心类型,配合原生动画事件实现动画生命周期的回调控制,能够覆盖状态反馈、入场出场、循环装饰等绝大多数动效场景,是构建流畅交互体验的基础。


7.1.1 transition 过渡动画

一、核心原理

过渡动画是状态驱动的补间动画,针对元素的两个状态(默认态与 hover 态、类名切换态等),在状态变化时自动计算中间帧,实现属性的平滑过渡。

它是最简单的 CSS 动效形式,适合交互触发的状态变化反馈。

二、核心属性

transition 是简写属性,包含四个子属性,按顺序为:属性名、时长、缓动函数、延迟时间。

|--------------------------------|----------------------------------|-------------------------------------------------------------------------|
| 属性 | 说明 | 取值示例 |
| transition-property | 指定应用过渡的 CSS 属性,all 表示所有可过渡属性 | all 、opacity 、transform |
| transition-duration | 过渡持续时间,单位秒(s)或毫秒(ms) | 0.3s 、300ms |
| transition-timing-function | 过渡缓动曲线,控制动画的速度变化 | ease 、linear 、ease-in-out 、cubic-bezier(0.4, 0, 0.2, 1) |
| transition-delay | 过渡延迟触发时间,单位秒或毫秒 | 0s 、100ms |

三、缓动函数详解

缓动函数决定动画的运动感,是动效自然度的核心:

  • linear:匀速线性运动,适合匀速旋转、位移动画
  • ease:默认值,慢-快-慢,自然的运动感,通用场景
  • ease-in:慢入快出,加速运动,适合元素出场、下落动画
  • ease-out:快入慢出,减速运动,适合元素入场、停止动画
  • ease-in-out:慢入慢出,两端平缓,适合悬停切换、来回过渡
  • cubic-bezier(x1,y1,x2,y2):自定义贝塞尔曲线,精准控制运动曲线
四、基础示例
css 复制代码
/* 按钮悬停过渡:所有属性 0.3 秒缓动过渡 */

.btn {

  background: #1677ff;

  transform: scale(1);

  transition: all 0.3s ease;

}

.btn:hover {

  background: #4096ff;

  transform: scale(1.05);

}
五、特点与边界
  • 优势:实现简单,声明式配置,性能优异,状态切换时自动反向过渡
  • 局限:仅支持两个状态之间的过渡,无法控制中间帧;无法主动播放,必须依赖状态触发;部分属性不可过渡(如 display 、float)
  • 最佳实践:优先使用 transform 和 opacity 实现动效,触发 GPU 合成,避免重排重绘,性能最优;避免使用 all,指定具体属性减少性能开销

7.1.2 animation 关键帧动画

一、核心原理

关键帧动画通过 @keyframes 规则定义动画过程中的多个关键帧状态,浏览器自动补全中间帧,支持多阶段、循环、反向等复杂动画效果,无需状态触发即可独立播放,是复杂 CSS 动效的标准实现方式。

二、核心属性

animation 是简写属性,包含 8 个子属性,完整控制动画的全生命周期。

|-------------------------------|----------------------|-----------------------------------------------------------------|
| 属性 | 说明 | 取值示例 |
| animation-name | 绑定的 @keyframes 关键帧名称 | fadeIn |
| animation-duration | 单次动画持续时间 | 1s |
| animation-timing-function | 单帧间的缓动函数 | ease-out |
| animation-delay | 动画延迟播放时间 | 0.2s |
| animation-iteration-count | 动画播放次数 | 1 、infinite(无限循环) |
| animation-direction | 动画播放方向 | normal (正向)、reverse (反向)、alternate(交替往返) |
| animation-fill-mode | 动画填充模式,控制动画前后的状态 | none 、forwards (停在结束帧)、backwards (提前应用起始帧)、both |
| animation-play-state | 动画播放状态 | running (运行)、paused(暂停) |

三、@keyframes 定义方式

支持两种关键帧定义方式:

  1. from / to:两帧动画,等价于 0% 和 100%
  2. 百分比:多帧动画,定义任意百分比位置的状态
css 复制代码
/* 淡入上移动画 */

@keyframes fadeInUp {

  0% {

    opacity: 0;

    transform: translateY(20px);

  }

  100% {

    opacity: 1;

    transform: translateY(0);

  }

}



/* 呼吸动画:无限循环交替 */

@keyframes breathe {

  0% { transform: scale(1); }

  50% { transform: scale(1.05); }

  100% { transform: scale(1); }

}



/* 应用动画 */

.fade-in {

  animation: fadeInUp 0.5s ease-out forwards;

}

.breathe {

  animation: breathe 2s ease-in-out infinite alternate;

}
四、与 transition 的核心对比

|----------|-----------------|---------------------|
| 对比维度 | transition 过渡 | animation 关键帧 |
| 状态数量 | 仅两个状态(起始-结束) | 支持任意多个关键帧状态 |
| 触发方式 | 依赖状态变化触发,无法主动播放 | 可自动播放,也可通过类名控制 |
| 循环能力 | 不支持循环,仅往返过渡 | 支持任意次数循环、无限循环 |
| 中间控制 | 无法控制中间过程 | 可精准控制每一帧的状态 |
| 事件回调 | 单次过渡对应一次事件 | 支持帧迭代、结束等多种事件 |
| 适用场景 | 交互状态反馈、悬停切换 | 复杂动画、入场出场、循环装饰、加载动效 |

五、fill-mode 重点说明

animation-fill-mode 是最容易被忽略的核心属性,决定动画播放前后元素的状态:

  • none:默认值,动画开始前和结束后都保持元素原有样式
  • forwards:动画结束后,保持最后一帧的状态,是入场动画最常用的配置
  • backwards:动画延迟期间,提前应用第一帧的状态,避免动画开始前的跳变
  • both:同时应用 forwards 和 backwards 的效果

7.1.3 动画事件:transitionend、animationend

CSS 动画原生提供生命周期事件,用于监听动画的开始、结束、迭代等节点,实现动画与业务逻辑的联动,是链式动画、状态切换、入场出场流程控制的核心。

一、transitionend 事件
触发时机

过渡动画完成时触发,每个过渡属性会独立触发一次。如果同时过渡多个属性,会触发多次事件。

核心属性
  • event.propertyName:完成过渡的属性名,用于区分不同属性的过渡
  • event.elapsedTime:过渡持续的时间,单位秒
基础示例
css 复制代码
const box = document.querySelector('.box');

box.addEventListener('transitionend', (e) => {

  // 只处理 opacity 过渡完成的逻辑

  if (e.propertyName === 'opacity') {

    console.log('透明度过渡完成');

    // 过渡结束后移除元素

    if (box.style.opacity === '0') {

      box.remove();

    }

  }

});
注意事项
  1. 过渡中途被中断(如状态再次变化、元素隐藏),不会触发 transitionend 事件。
  2. 过渡时长为 0 时不会触发事件。
  3. 多个属性过渡会触发多次,需通过 propertyName 过滤目标事件。
二、animation 相关事件

关键帧动画提供三个生命周期事件,覆盖完整动画流程:

|------------------------|--------------|-----------------------------------------|
| 事件名 | 触发时机 | 核心说明 |
| animationstart | 动画开始播放时触发 | 延迟时间结束、动画正式启动时触发 |
| animationiteration | 动画每完成一次迭代时触发 | 循环动画每次循环结束触发,仅 iteration-count > 1 时有效 |
| animationend | 动画全部播放完成时触发 | 所有迭代完成后触发,无限循环不会触发 |

基础示例:入场动画结束后执行业务逻辑
css 复制代码
const modal = document.querySelector('.modal');

modal.addEventListener('animationend', () => {

  console.log('弹窗入场动画完成');

  // 动画结束后聚焦输入框

  modal.querySelector('input').focus();

});
三、典型应用场景
  • 离场动画结束后移除 DOM 元素,避免元素残留
  • 链式动画:前一个动画结束后触发下一个动画,实现序列动效
  • 动画完成回调:入场动画结束后初始化业务逻辑、聚焦交互
  • 状态同步:动画结束后更新业务状态,避免动画未完成就执行操作
相关推荐
志尊宝1 小时前
Vue3 零基础每日笔记(080):Vue3 + ECharts 数据可视化——封装可复用图表组件
前端·javascript·vue.js·笔记·信息可视化·echarts
阿狗童鞋1 小时前
前端工程化实战指南
前端
用户4402818278071 小时前
我用 TRAE 一晚上从零撸了个微信投票小程序: 17 个云函数 + 11 个页面的全链路实战
前端
BullSmall1 小时前
SonarQube 9.9.8-community 适配 Jenkins 版本说明
java·前端·jenkins
tryCbest1 小时前
第一篇:HTML5 核心知识全解 + 项目起步
前端·html·html5
百度一下吧1 小时前
CSS 伪类使用与实践:从入门到进阶
前端·css
hunterandroid1 小时前
android方案 : Multiplatform 跨平台开发实战:一套代码,多端运行
android·前端
百度一下吧1 小时前
CSS3 之后新增的特性:从 CSS4 到现代 CSS 的演进
前端·css·css3