@keyframes - 关键帧动画
创建复杂的、可重复的动画效果
什么是 @keyframes?
@keyframes 用于定义动画的关键帧,可以创建比 transition 更复杂的动画效果。它允许你精确控制动画在不同时间点的状态。
- 关键帧:定义动画在特定时间点的样式
- 可重复:动画可以循环播放
- 更灵活:可以定义多个中间状态
- 自动播放:页面加载时自动开始
基本语法
/* 方式 1:使用 from 和 to */
@keyframes animationName {
from { transform: translateX(0); }
to { transform: translateX(100px); }
}
/* 方式 2:使用百分比 */
@keyframes animationName {
0% { transform: translateX(0); }
50% { transform: translateX(100px); }
100% { transform: translateX(0); }
}
/* 应用动画 */
.element {
animation: animationName 2s ease-in-out infinite;
}
from/to vs 百分比
使用 from 和 to
- from - 等同于 0%,表示动画的起始状态
- to - 等同于 100%,表示动画的结束状态
- 适用场景:简单的两个状态之间的过渡
- 优点:语义清晰,代码简洁
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
使用百分比
- 0% - 动画开始时的状态
- 50% - 动画进行到一半时的状态
- 100% - 动画结束时的状态
- 适用场景:需要多个中间状态的复杂动画
- 优点:可以精确控制动画的每个阶段
@keyframes complexMove {
0% { transform: translateX(0); }
25% { transform: translateX(100px); }
50% { transform: translateX(100px) translateY(50px); }
75% { transform: translateX(0) translateY(50px); }
100% { transform: translateX(0) translateY(0); }
}
选择建议:如果只有开始和结束两个状态,使用 from/to 更简洁;如果需要多个中间状态,使用百分比更灵活
示例对比:from/to vs 百分比
下面两个动画效果完全相同,只是写法不同
使用 from/to
@keyframes simple {
from { opacity: 0; }
to { opacity: 1; }
}
使用百分比
@keyframes simple {
0% { opacity: 0; }
100% { opacity: 1; }
}
等价关系:from = 0%,to = 100%。两种写法完全等价,选择你喜欢的即可
示例 1:滑入动画(使用 from/to)
元素从左侧滑入并淡入
@keyframes slideIn {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.box {
animation: slideIn 1s ease-out;
}
示例 2:弹跳动画
元素持续上下弹跳
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-30px);
}
}
.box {
animation: bounce 1s ease-in-out infinite;
/* infinite 表示无限循环 */
}
示例 3:颜色变化
背景色在多个颜色之间循环变化
@keyframes colorChange {
0% { background: #10b981; }
33% { background: #3b82f6; }
66% { background: #8b5cf6; }
100% { background: #10b981; }
}
.box {
animation: colorChange 3s ease-in-out infinite;
}
示例 4:3D 旋转
元素在 3D 空间中持续旋转
@keyframes rotate3d {
from {
transform: rotate3d(0, 1, 0, 0deg);
}
to {
transform: rotate3d(0, 1, 0, 360deg);
}
}
.box {
animation: rotate3d 3s linear infinite;
}
animation 属性详解
.element {
animation: name duration timing-function delay iteration-count direction fill-mode;
}
- animation-name - 动画名称(@keyframes 定义的名称)
- animation-duration - 持续时间(如 2s, 500ms)决定动画何时结束
- animation-timing-function - 缓动函数(ease, linear, ease-in-out 等)
- animation-delay - 延迟时间(如 1s)
- animation-iteration-count - 播放次数(数字或 infinite)
- animation-direction - 播放方向(见下方详解)
- animation-fill-mode - 填充模式(见下方详解)
重要:动画从 0% 到 100% 的时间由 animation-duration 决定。例如 duration: 2s 表示动画会在 2 秒内完成从 0% 到 100% 的所有关键帧
animation-direction 详解
控制动画的播放方向
normal(默认)
正常播放:0% → 100%
reverse
反向播放:100% → 0%
alternate
交替播放:正向 → 反向 → 正向...
alternate-reverse
反向交替:反向 → 正向 → 反向...
.normal {
animation-direction: normal;
}
.reverse {
animation-direction: reverse;
}
.alternate {
animation-direction: alternate;
}
.alternate-reverse {
animation-direction: alternate-reverse;
}
animation-fill-mode 简介
控制动画开始前和结束后元素的状态
- none - 默认值,延迟期间和结束后都不应用动画样式
- forwards - 动画结束后保持最后一帧的状态(最常用!)
- backwards - 延迟期间应用第一帧样式
- both - 结合 backwards 和 forwards 的效果
🎯 想深入理解 fill-mode?
👉 点击查看 animation-fill-mode 详细演示页面
包含更直观的对比演示、完整代码示例和最佳实践建议
/* 基本用法 */
.element {
animation-fill-mode: forwards; /* 保持最后一帧 */
}
/* 简写形式 */
.element {
animation: myAnimation 2s ease-out forwards;
}