Menu

CSS 애니메이션: @keyframes, 속성, 예제

CSS 애니메이션은 @keyframes에 정의한 단계를 따라 요소를 스스로, 원하는 만큼 반복해서 움직여요. @keyframes 문법, 여덟 가지 animation 속성, fill-mode와 direction, 로딩 표시, 일시정지, 움직임 줄이기 설정을 존중하는 법을 알아봐요.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

예제 하나로 보는 CSS 애니메이션

애니메이션은 두 부분으로 되어 있어요. 단계를 설명하는 @keyframes, 그리고 지속 시간과 함께 요소에 적용하는 animation 속성이에요. 이 카드는 페이지가 로드되면 미끄러지면서 나타나요.

코드를 고치면(또는 지속 시간을 2s로 바꾸면) 미리보기가 다시 로드되어 카드가 다시 들어오는 걸 볼 수 있어요. @media (prefers-reduced-motion: reduce) 블록은 시스템이 동작 줄이기로 설정된 독자에게만 키프레임을 페이드로 바꿔요.

@keyframes 문법

@keyframes pulse {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}
  • from은 0%, to는 100%와 같아요.
  • 퍼센트 단계를 필요한 만큼 추가하세요. 스타일이 같은 단계는 한 줄을 공유할 수 있어요. 0%, 100% { ... }
  • 첫 키프레임이나 마지막 키프레임에 없는 속성은 요소 자신의 값에서부터, 또는 그 값까지 애니메이션돼요.
  • 이름(pulse)은 animation-name에 넘기는 값이에요. 대소문자를 구분하고, none 같은 키워드면 안 돼요.

animation 속성

속성정하는 것기본값
animation-name실행할 @keyframesnone
animation-duration한 주기의 길이0s
animation-timing-function키프레임 사이의 속도 곡선ease
animation-delay첫 주기 전 대기(음수면 중간부터 시작)0s
animation-iteration-count주기 수, 또는 infinite1
animation-directionnormal, reverse, alternate, alternate-reversenormal
animation-fill-mode전후 스타일: none, forwards, backwards, bothnone
animation-play-staterunning 또는 pausedrunning

단축 속성은 거의 어떤 순서로든 받아요. 유일한 규칙은 첫 번째 시간 값이 지속 시간이고 두 번째가 지연이라는 거예요.

.loader {
  animation: pulse 1.2s ease-in-out 0.2s infinite alternate both;
  /*         name  duration timing  delay count   direction fill */
}

direction과 fill-mode 실시간으로 보기

direction, fill mode, 횟수를 고르고 Play를 누르세요. 상자가 트랙 끝까지 200px 움직여요. 표시 창은 애니메이션이 끝난 뒤 상자가 어디서 멈췄는지 알려 줘요.

볼 것들이에요.

  • fill-mode: none(기본값): 마지막 프레임 뒤에 상자가 x = 0으로 튀어 돌아가고 다시 주황색이 돼요.
  • forwards: 마지막 키프레임에 머물러요. normal이면 x = 200에 초록색이고, reverse면 마지막으로 재생된 키프레임이 from이라서 x = 0에 파란색으로 끝나요.
  • 횟수 2의 alternate는 갔다가 돌아와서, forwards여도 x = 0에서 끝나요.

무한 반복: 로딩 표시

infinite는 영원히 반복하고, 자식마다 animation-delay를 주면 차례로 움직이도록 엇갈려요. 반복은 차분하게 유지하세요. 느리게, 작게, 깜빡임 없이요.

aria-label이 있는 role="status"는 스크린 리더 사용자에게 무언가 로딩 중이라고 알려 줘요. 점만으로는 알 수 없어요. 회전하는 원은 회전 페이지를 보세요.

애니메이션 일시정지와 제어

animation-play-state: paused는 애니메이션을 그 자리에 멈추고, running은 거기서 이어가요. 아래 막대에 마우스를 올리면 멈춰요.

JavaScript에서 element.getAnimations()는 실행 중인 CSS 애니메이션을 돌려주고, 각각 pause(), play(), cancel()과 읽거나 지정할 수 있는 currentTime을 가져요. animationend 이벤트는 무한이 아닌 애니메이션이 끝날 때, animationiteration은 각 주기가 끝날 때 발생해요.

움직임 줄이기를 존중하고, 절대 깜빡이지 마세요

모든 애니메이션에 적용되는 접근성 규칙이 두 가지 있어요.

  1. 움직임 줄이기. 움직임 때문에 몸이 불편해져서 시스템에 움직임을 줄여 달라고 요청하는 사람들이 있어요. 가장 안전한 패턴은 그런 요청이 없을 때만 움직임을 더하는 거예요.
@media (prefers-reduced-motion: no-preference) {
  .hero-title { animation: slide-in 0.8s ease-out both; }
}
  1. 깜빡임 금지. 1초에 세 번 넘게 깜빡이는 콘텐츠는 발작을 일으킬 수 있어요. 빠르고 대비가 큰 깜빡임은 아예 피하세요.

애니메이션을 부드럽게 유지하기

가능하면 transform과 opacity를 애니메이션하세요. 브라우저가 페이지 레이아웃을 다시 하지 않고 적용할 수 있어서 느린 휴대폰에서도 부드러워요. width, height, top, left, margin을 애니메이션하면 매 프레임 레이아웃을 다시 계산해요. 요소를 옮길 때는 transform 페이지의 translate()를 쓰세요.

자주 하는 실수

  • 지속 시간 없음. 기본 지속 시간이 0s라서 animation: fade;는 아무것도 하지 않아요.
  • 일치하지 않는 이름. animation-name은 대소문자까지 @keyframes 이름과 정확히 같아야 해요.
  • 끝에서 튀어 돌아가기. 마지막 키프레임을 유지하려면 forwards(또는 both)를 추가하세요.
  • 지연된 애니메이션이 시작되기 전의 깜빡임. animation-delay 동안 요소는 원래 스타일을 보여 줘요. backwards(또는 both)가 지연 동안 첫 키프레임을 적용해요.
  • 같은 값을 지정해서 애니메이션 재시작하기. 같은 animation을 다시 지정해도 아무 일도 없어요. 위의 Play 버튼처럼 지우고, 리플로우를 강제하고(el.offsetWidth), 다시 지정하세요.
  • display 애니메이션하기. 즉시 바뀌어요. 대신 opacity와 transform을 애니메이션하세요.

자주 묻는 질문

CSS로 애니메이션은 어떻게 만드나요?

@keyframes name { from { ... } to { ... } }로 단계를 정의하고, animation 속성과 지속 시간으로 요소에 적용해요. animation: name 1s ease-out; 지속 시간의 기본값이 0s라서 지속 시간은 필수예요.

animation-fill-mode: forwards는 무엇을 하나요?

애니메이션이 끝난 뒤에도 마지막 키프레임의 스타일을 유지해요. 없으면 요소가 원래 스타일로 튀어 돌아가요. backwards는 지연 시간 동안 첫 키프레임을 적용하고, both는 둘 다 해요.

CSS 애니메이션을 무한 반복하려면 어떻게 하나요?

animation-iteration-count: infinite를 지정하거나 단축 속성에 infinite를 추가하세요. animation: spin 1s linear infinite; alternate를 추가하면 주기마다 앞으로 갔다가 뒤로 재생해요.

CSS animation과 transition은 무엇이 다른가요?

transition은 보통 hover나 클래스 변경으로 속성이 바뀔 때 두 값 사이를 애니메이션해요. animation은 적용되자마자 스스로 실행되고, 키프레임을 몇 개든 가질 수 있으며, 반복, 역재생, 일시정지를 할 수 있어요.

CSS 애니메이션은 어떻게 일시정지하나요?

요소에 animation-play-state: paused를 지정하세요. 예를 들어 :hover나 JavaScript가 추가하는 클래스에서요. 다시 running으로 지정하면 멈춘 곳에서 이어져요.

움직임 줄이기를 선호하는 사용자에게 애니메이션을 끄려면 어떻게 하나요?

애니메이션을 @media (prefers-reduced-motion: no-preference) { ... }로 감싸거나, @media (prefers-reduced-motion: reduce) { ... } 안에서 제거하세요. 이 쿼리는 사용자 운영체제의 동작 줄이기 설정을 따라요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기