pile·
프론트엔드·카카오 엔터테인먼트 FE카카오 엔터테인먼트 FE·

웹 애니메이션을 구현하는 4가지 방법 (feat. animation API)

웹 애니메이션을 구현하는 CSS transition, CSS animation, SVG animation, Web Animation API 4가지 방법을 동일한 햄버거 메뉴 버튼 인터랙션 예제로 비교하는 카카오엔터테인먼트 FE 팀의 기술 글이다. 각 방법의 특성·적합한 사용 상황·코드 패턴을 나란히 놓고 장단점을 실용적으로 설명한다.

핵심 포인트
  • CSS transition: 가장 대중적인 방식, 클래스 토글로 상태 전환 시 두 상태 사이 보간 자동 처리, 러닝커브 낮음
  • CSS animation: @keyframes로 여러 단계의 복잡한 인터랙션 표현 가능, 단순 상태 전환보다 연쇄 동작·반복 애니메이션에 적합
  • CSS animation으로 클릭 인터랙션 구현은 animationend 이벤트와 클래스 관리가 복잡해지는 단점 존재
  • SVG animation: 경로(path) 기반 도형 변환 애니메이션에 적합, 복잡한 모핑 효과를 CSS만으로 구현하기 어려운 경우 활용
  • Web Animation API: JavaScript에서 직접 키프레임과 타이밍을 제어, CSS animation의 클래스 관리 없이 동적 애니메이션 조작 가능
  • 4가지 방법 모두 동일한 인터랙션을 구현할 수 있으나 요구사항 복잡도와 제어 필요 수준에 따라 선택이 달라짐
상세 정리
  • CSS transition: .stick { transition: all 0.3s } 선언 후 .close 클래스 토글로 transform·scale 변환, 가장 간결
  • CSS transition 동작 원리: 클래스 변경으로 스타일이 바뀌면 transition 속성이 두 상태 사이를 자동으로 보간
  • CSS animation: @keyframes rotate45, shrink 등으로 각 단계 스타일 정의, forwards로 마지막 상태 유지
  • CSS animation의 역방향 재생: animation-direction: reverse를 새 클래스로 적용하되 animationend 이벤트에서 클래스 정리 필요
  • CSS animation 한계: 클릭 반복 방지 로직과 animationend 처리가 중첩되어 코드 복잡도 증가
  • SVG animation: SMIL 또는 CSS와 결합해 path 데이터(d 속성) 변환으로 유기적 모핑 애니메이션 구현
  • Web Animation API: element.animate([keyframe1, keyframe2], {duration, fill}) 패턴으로 JavaScript에서 직접 애니메이션 인스턴스 생성
  • Web Animation API 장점: animation.reverse()로 방향 전환, animation.pause()/play()/finish() 등 재생 상태를 코드로 정밀 제어
  • animation.onfinish 콜백으로 완료 후 처리를 CSS animationend 이벤트 없이 깔끔하게 처리 가능
  • CSS transition/animation이 선언적이라면 Web Animation API는 명령형 — 동적 값 계산이나 외부 상태에 따른 애니메이션 제어에 유리
왜 읽나같은 예제로 4가지 방법을 코드 단위로 비교하므로 상황에 맞는 애니메이션 방법 선택 기준을 한 번에 잡을 수 있다.
카카오 엔터테인먼트 FE
카카오 엔터테인먼트 FE 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    항공 프론트엔드 구축기 (7/10): 창구를 하나만 두었습니다

    여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.

    요약 이어보기
    #react#typescript#webview+2