虽然 transitions 在两个状态之间进行动画,@keyframes 动画定义了一个多步序列,可以自动运行、循环,并通过许多中间状态进行移动。
定义和应用动画
css
slide-in {
{ : (-); : ; }
{ : (); : ; }
}
{
: slide-in ease-out;
}
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-30px); } /* peak of the bounce */
100% { transform: translateY(0); }
}
百分比让你在一个动画中编排几个阶段——这是简单 transition 无法实现的。
.spinner {
animation: spin 1s linear infinite;
/* │ │ │ └── iteration-count (infinite = loop forever) */
/* │ │ └───────── timing function */
/* │ └────────────── duration */
/* └─────────────────── @keyframes name */
}
@keyframes spin { to { transform: rotate(360deg); } } /* classic loading spinner */
其他属性:animation-delay、animation-direction: alternate(来回)、animation-fill-mode: forwards(保持最终状态)、animation-play-state: paused。
/* ✅ GPU-composited, 60fps */
@keyframes good { to { transform: scale(1.1); opacity: 0.5; } }
/* ❌ animating width/height/top forces layout every frame → jank */
@keyframes bad { to { width: 300px; top: 50px; } }
关键帧动画在每一帧上运行,因此动画化触发布局的属性的成本远高于动画化 transform/opacity。
@media (prefers-reduced-motion: reduce) {
.spinner { animation: none; } /* honor users sensitive to motion */
}
关键帧动画为加载器、注意力提示、入场和循环效果提供动力——transitions 无法表达这些(多步、自动运行、无限)。
了解简写语法、坚持使用 transform/opacity 以获得流畅性,以及尊重 prefers-reduced-motion 使你能够构建丰富的动画,同时保持性能和无障碍。