transition이 두 상태 사이를 애니메이션하는 반면, @keyframes 애니메이션은 자동으로 실행되고, 반복되며, 여러 중간 상태를 거치는 다단계 시퀀스를 정의합니다.
애니메이션 정의와 적용
css
slide-in {
{ : (-); : ; }
{ : (); : ; }
}
{
: slide-in ease-out;
}
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-30px); } /* 튀어오름의 정점 */
100% { transform: translateY(0); }
}
백분율은 하나의 애니메이션에서 여러 단계를 안무할 수 있게 합니다 — 단순한 transition으로는 불가능합니다.
.spinner {
animation: spin 1s linear infinite;
/* │ │ │ └── iteration-count (infinite = 영원히 반복) */
/* │ │ └───────── timing function */
/* │ └────────────── duration */
/* └─────────────────── @keyframes 이름 */
}
@keyframes spin { to { transform: rotate(360deg); } } /* 전형적인 로딩 스피너 */
기타 속성: animation-delay, animation-direction: alternate(왕복), animation-fill-mode: forwards(최종 상태 유지), animation-play-state: paused.
/* ✅ GPU 합성, 60fps */
@keyframes good { to { transform: scale(1.1); opacity: 0.5; } }
/* ❌ width/height/top 애니메이션은 매 프레임 레이아웃을 강제 → 끊김 */
@keyframes bad { to { width: 300px; top: 50px; } }
keyframe 애니메이션은 매 프레임 실행되므로, 레이아웃을 유발하는 속성을 애니메이션하는 것이 transform/opacity보다 훨씬 비쌉니다.
@media (prefers-reduced-motion: reduce) {
.spinner { animation: none; } /* 모션에 민감한 사용자를 존중 */
}
keyframe 애니메이션은 transition으로는 표현할 수 없는(다단계, 자동 실행, 무한) 로더, 주의 환기, 등장 효과, 반복 효과를 구동합니다.
단축 속성을 알고, 부드러움을 위해 transform/opacity를 고수하며, prefers-reduced-motion을 존중하면 성능 좋고 접근성 있는 풍부한 모션을 만들 수 있습니다.