# 모션 & 애니메이션 --- ## 원칙 - 모션은 UI의 상태 변화를 명확히 전달하기 위한 수단이다. - 불필요한 애니메이션은 사용하지 않는다. - 모든 모션은 `prefers-reduced-motion` 미디어 쿼리를 존중한다. --- ## Duration (지속 시간) | 이름 | 값 | Tailwind | 용도 | |------|----|----------|------| | instant | 0ms | — | 즉각 반응 (포커스, 선택) | | fast | 100ms | `duration-100` | 버튼 hover, 색상 전환 | | normal | 200ms | `duration-200` | 패널 열기, 드롭다운 | | slow | 300ms | `duration-300` | 모달, 사이드바 슬라이드 | | slower | 500ms | `duration-500` | 페이지 전환, 스켈레톤 | 기본값: `duration-200`. 특별한 이유 없이 300ms를 초과하지 않는다. --- ## Easing (가속도 곡선) | 이름 | 값 | Tailwind | 용도 | |------|----|----------|------| | ease-out | `cubic-bezier(0, 0, 0.2, 1)` | `ease-out` | 진입 애니메이션 (요소 나타남) | | ease-in | `cubic-bezier(0.4, 0, 1, 1)` | `ease-in` | 퇴장 애니메이션 (요소 사라짐) | | ease-in-out | `cubic-bezier(0.4, 0, 0.2, 1)` | `ease-in-out` | 상태 전환 (toggle, expand) | | spring | `cubic-bezier(0.34, 1.56, 0.64, 1)` | — | 강조 효과 (알림, 배지) | 기본 조합: 진입 `ease-out`, 퇴장 `ease-in`. --- ## 패턴 ### Hover / Active 버튼, 카드, 링크 등 상호작용 요소. ```css transition-colors duration-100 ease-out ``` 포인터 커서 피드백: ```css active:scale-[0.98] transition-transform duration-75 ``` ### 진입 (Fade + Slide) 모달, 드롭다운, Toast 등 요소가 나타날 때. ```css /* 아래에서 위로 */ translate-y-2 opacity-0 → translate-y-0 opacity-100 transition-[transform,opacity] duration-200 ease-out /* 위에서 아래로 (드롭다운) */ -translate-y-2 opacity-0 → translate-y-0 opacity-100 transition-[transform,opacity] duration-200 ease-out ``` ### 퇴장 (Fade + Slide) ```css translate-y-0 opacity-100 → translate-y-2 opacity-0 transition-[transform,opacity] duration-150 ease-in ``` ### 사이드바 / 패널 슬라이드 ```css -translate-x-full → translate-x-0 transition-transform duration-300 ease-out ``` ### 모달 배경 (Backdrop) ```css opacity-0 → opacity-100 transition-opacity duration-200 ease-out ``` ### 스켈레톤 로딩 ```css animate-pulse ``` ### 회전 (로딩 스피너) ```css animate-spin ``` ### 토글 (Accordion, Expand) 높이 애니메이션은 `max-height` 트릭을 사용한다. ```css max-h-0 overflow-hidden → max-h-screen transition-[max-height] duration-300 ease-in-out ``` --- ## prefers-reduced-motion 모든 모션은 사용자의 시스템 설정을 존중해야 한다. ### Tailwind 설정 ```html
``` ### CSS 전역 설정 (권장) ```css @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } ``` ### React Hook ```tsx const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; const duration = prefersReducedMotion ? 0 : 200; ``` --- ## 금지 사항 - 3초 이상의 루프 애니메이션 (사용자 주의 분산) - 화면 전체를 덮는 플래시/깜박임 효과 - 스크롤에 연동된 복잡한 패럴랙스 - `animation-duration: 0` 직접 설정 (prefers-reduced-motion 우회 금지)