animation-fill-mode 详细演示
理解"延迟期间"和四种填充模式的区别
什么是 animation-fill-mode?
animation-fill-mode
控制动画开始前和结束后元素的状态。它决定了元素在动画的"延迟期间"和"结束后"应该显示什么样式。
💡 什么是"延迟期间"?
当你设置
animation-delay: 2s 时,动画不会立即开始,而是等待 2 秒。这 2 秒就是"延迟期间"。
下面的演示中,所有动画都有 2 秒延迟。点击按钮后,仔细观察前 2 秒方块的位置和颜色!
四种填充模式
- none - 默认值,延迟期间和结束后都不应用动画样式
- forwards - 动画结束后保持最后一帧的状态(最常用!)
- backwards - 延迟期间应用第一帧样式
- both - 结合 backwards 和 forwards 的效果
backwards 的作用对比
动画:从左侧(红色)滑到中间(绿色),有 2 秒延迟
❌ none(默认)
• 0-2秒:方块在中间(绿色)等待
• 2秒时:突然跳到左边(红色)
• 2-3.5秒:从左边滑到中间
• 3.5秒后:回到中间(绿色)
.box {
animation: slideFromLeft 1.5s ease-out 2s 1 none;
/* 延迟期间保持原始状态 */
}
✅ backwards
• 立即:方块跳到左边(红色)
• 0-2秒:在左边等待
• 2-3.5秒:从左边滑到中间
• 3.5秒后:回到中间(绿色)
.box {
animation: slideFromLeft 1.5s ease-out 2s 1 backwards;
/* 延迟期间立即应用第一帧 */
}
🎯 关键区别
none:
延迟期间保持原始状态(中间),动画开始时才跳到起始位置(左边)
backwards:
点击后立即跳到起始位置(左边),然后在那里等待延迟结束
forwards 的作用对比
动画:从中间(绿色)滑到右边(橙色半透明),有 2 秒延迟
❌ none(默认)
• 0-2秒:在中间(绿色)等待
• 2-3.5秒:滑到右边(橙色半透明)
• 3.5秒后:回到中间(绿色)
.box {
animation: slideToRight 1.5s ease-out 2s 1 none;
/* 动画结束后回到原始状态 */
}
✅ forwards
• 0-2秒:在中间(绿色)等待
• 2-3.5秒:滑到右边(橙色半透明)
• 3.5秒后:停在右边(橙色半透明)
.box {
animation: slideToRight 1.5s ease-out 2s 1 forwards;
/* 动画结束后保持最后一帧 */
}
🎯 关键区别
none:
动画结束后,元素"闪回"到原始状态(中间,绿色)
forwards:
动画结束后,元素保持在最后一帧的状态(右边,橙色半透明)
both = backwards + forwards
动画:从左侧(红色)滑到右边(橙色半透明),有 2 秒延迟
both(完美组合)
• 立即:跳到左边(红色)- backwards
• 0-2秒:在左边等待
• 2-3.5秒:从左边滑到右边
• 3.5秒后:停在右边(橙色半透明) - forwards
@keyframes slideLeftToRight {
from {
transform: translate(-250%, -50%);
background: var(--error);
}
to {
transform: translate(150%, -50%);
background: var(--warning);
opacity: 0.3;
}
}
.box {
animation: slideLeftToRight 1.5s ease-out 2s 1 both;
}
完整对比表格
延迟期间:原始状态 | 结束后:原始状态
延迟期间:第一帧 ✨ | 结束后:原始状态
延迟期间:原始状态 | 结束后:最后一帧 ✨
延迟期间:第一帧 ✨ | 结束后:最后一帧 ✨
/* 动画定义 */
@keyframes slideFromLeft {
from {
transform: translate(-250%, -50%); /* 在左边 */
background: #ef4444; /* 红色 */
}
to {
transform: translate(-50%, -50%); /* 在中间 */
background: #10b981; /* 绿色 */
}
}
/* 应用动画 */
.box {
animation: slideFromLeft 1.5s ease-out 2s 1 backwards;
/* 动画名 时长 缓动 延迟 次数 填充模式 */
}
详细语法说明
/* 假设动画定义:从透明到不透明 */
@keyframes fadeOut {
from { opacity: 0.2; } /* 第一帧:透明 */
to { opacity: 1; } /* 最后一帧:不透明 */
}
/* 元素原始状态:不透明 */
.box {
opacity: 1;
}
/* none: 延迟期间保持原始状态,结束后回到原始状态 */
.none {
animation: fadeOut 1s linear 2s 1 none;
/* 延迟 2 秒期间:opacity: 1(原始)
动画播放:opacity: 0.2 → 1
动画结束后:opacity: 1(原始)*/
}
/* backwards: 延迟期间立即应用第一帧 */
.backwards {
animation: fadeOut 1s linear 2s 1 backwards;
/* 延迟 2 秒期间:opacity: 0.2(第一帧!)
动画播放:opacity: 0.2 → 1
动画结束后:opacity: 1(原始)*/
}
/* forwards: 结束后保持最后一帧 */
.forwards {
animation: fadeOut 1s linear 2s 1 forwards;
/* 延迟 2 秒期间:opacity: 1(原始)
动画播放:opacity: 0.2 → 1
动画结束后:opacity: 1(最后一帧!)*/
}
/* both: 结合 backwards 和 forwards */
.both {
animation: fadeOut 1s linear 2s 1 both;
/* 延迟 2 秒期间:opacity: 0.2(第一帧!)
动画播放:opacity: 0.2 → 1
动画结束后:opacity: 1(最后一帧!)*/
}
总结与最佳实践
📝 四种模式总结
- none: 延迟期间和结束后都用原始样式
- forwards: 结束后保持最后一帧(最常用!)
- backwards: 延迟期间应用第一帧
- both: 延迟期间用第一帧 + 结束后用最后一帧
💡 实际应用建议
forwards
最常用,可以让元素在动画结束后保持最终状态,避免"闪回"到初始状态。
backwards
在有延迟的动画中很有用,可以让元素在延迟期间就显示动画的起始状态,避免突然跳变。
both
适合既有延迟又需要保持结束状态的场景,是 backwards 和 forwards 的组合。