🎨 Frontend CSS6. 모션 (Transition·Animation)📖 개요

06 — Motion (시간 축에서의 변화)

한 줄 답: 모션은 **CSS 속성값의 시간 보간(interpolation)**이다. 우리가 신경 써야 할 것은 “무엇을 보간하느냐” (transform·opacity) × “어떻게 보간하느냐” (timing function·composite) × “누가 트리거하느냐” (state·scroll·navigation) × “누가 멀미하느냐” (prefers-reduced-motion)의 4축이다.


이 챕터가 답하는 질문

  1. transitionanimation은 정확히 무엇이 다른가?
  2. top: 100px로 슬라이드하면 왜 끊기고, transform: translateY(100px)은 왜 부드러운가?
  3. will-change: transform을 모든 요소에 주면 빨라지는가?
  4. display: none인 요소가 block이 되면서 페이드인 시키려면?
  5. Next.js 페이지 전환에서 카드 하나가 그대로 다음 화면으로 “이동”하게 하려면?
  6. JS 없이 스크롤 진행도 따라가는 애니메이션은 어떻게?
  7. 멀미를 호소하는 사용자에게 모션을 어떻게 꺼주는가?
  8. FLIP 기법(Pinterest·Twitter)은 정확히 무엇을 줄이는 기법인가?

이 8개에 답할 수 있다면, *“왜 우리 앱이 튀는가”*는 *“렌더 파이프라인의 어느 단계가 60fps를 깨는가”*로 환원된다.


챕터 구조

문서다루는 것핵심 키워드
01-transition상태 전환 보간transition, timing-function, transition-behavior: allow-discrete
02-animation키프레임 기반 자율 애니메이션@keyframes, animation-composition, fill-mode, replace/add/accumulate
03-transform2D/3D 변환translate·rotate·scale·skew, transform-origin, perspective, 3D context
04-rendering-perfLayout·Paint·Composite 파이프라인GPU promotion, jank, will-change, FLIP, Compositor-only props
05-view-transitionsView Transitions APISame-Doc(SPA), Cross-Doc(MPA, 2024), view-transition-name, morphing
06-scroll-driven스크롤 진행도 ↔ 애니메이션animation-timeline, scroll-timeline, view-timeline, view()
07-accessibility모션과 vestibular disorderprefers-reduced-motion, 멀미, motion design ethics

5-레이어 모델 안에서의 위치

모션은 Visual의 결과를 시간으로 늘인 것이다. 그래서 05-color-visual(opacity, filter, gradient) 다음에, 07-responsive(viewport 단위) 앞에 놓인다.


Why — 왜 별도의 챕터인가

UI의 체감 품질은 정적인 픽셀이 아니라 그 픽셀이 어떻게 움직이는가에서 갈린다.

  • 16ms 지연 = 60fps, 33ms = 30fps, 100ms 이상 = “끊긴다”의 인지 임계.
  • 정확히 같은 디자인이라도 transform 기반 슬라이드 vs left 기반 슬라이드의 CPU 사용량은 10배 이상 차이난다.
  • prefers-reduced-motion을 무시한 캐러셀은 vestibular disorder 사용자에게 두통·구토를 유발한다 (WCAG 2.3.3 Animation from Interactions).
  • 2024년 이후 View Transitions·Scroll-driven Animations가 Baseline에 진입하면서 JS 라이브러리(Framer Motion, GSAP) 일부 영역이 CSS로 흡수됐다.

이 챕터는 *“애니메이션을 추가하면 더 멋져진다”*는 가정을 *“애니메이션은 렌더 파이프라인 비용과 인지 부하의 거래”*라는 공학적 결정으로 바꾼다.


How — 어떻게 읽나

순서대로 5시간. 의존성이 있는 누적형 챕터다.

#파일읽는 데전제
0101-transition25분02-layout(box model), 01-cascade
0202-animation30분01-transition
0303-transform30분0-foundations(좌표계), 02-layout
0404-rendering-perf35분01·02·03 모두
0505-view-transitions25분04 (composite)
0606-scroll-driven25분02 (keyframes), 04 (perf)
0707-accessibility15분01~06 전부 (모든 모션에 적용되는 메타 규칙)
  • 빠르게 훑고 싶다면: 010407만 봐도 사고 절반은 막힌다.
  • SPA 전환 만들기: 03 + 04 + 05.
  • 랜딩 페이지: 02 + 06 + 07.

What — 한 페이지 요약

문서한 줄 결론
01transition상태 변화의 보간이다. transition-behavior: allow-discretedisplay:none 트랜지션을 가능케 한다.
02animation자율적 키프레임 시퀀스다. animation-composition: add는 변환을 덧붙이는 새 모델.
03transform레이아웃에 영향 없는 좌표 변환이다. Composite-only라 60fps에 가장 친화적.
04렌더는 Layout → Paint → Composite 파이프라인. transform·opacity는 마지막 단계만 트리거 — 그래서 부드럽다. will-change가설 선언이다, 남발하면 메모리 폭발.
05View Transitions는 DOM 두 상태를 캡처해 그 사이를 보간. 2024년 Cross-Document(MPA) 전환 Chrome 안착.
06Scroll-driven은 animation-timeline: scroll() / view()스크롤을 시간 축으로 변환. JS 없는 패럴랙스·진행 바·sticky 페이드.
07@media (prefers-reduced-motion: reduce)의무. 멀미는 디자인 문제가 아니라 접근성 결함이다.

What-if — 잘못 만지면

  • top/left로 슬라이드 → 매 프레임 Layout 재계산 → 모바일에서 30fps도 못 지킨다 (transform으로 바꿔라)
  • backdrop-filter에 animation → iOS Safari에서 GPU 메모리 폭증, jank
  • will-change: transform을 100개 카드에 → 레이어 100개 → 모바일 GPU 메모리 한계 초과로 오히려 더 느려짐
  • prefers-reduced-motion 미고려 → vestibular 사용자에게 두통, WCAG 2.3.3 위반
  • View Transitions의 view-transition-name여러 요소에 같은 이름 → 에러로 트랜지션 자체가 취소
  • Scroll-driven에 width 애니메이션 → 스크롤할 때마다 Layout → 스크롤 자체가 끊긴다

Insight — 한 단락 이야기

“모션의 역사는 CSS가 GPU와 화해하는 역사다.”

2009년 Webkit이 -webkit-transform을 도입할 때, 핵심은 transform이 layout을 트리거하지 않는다는 점이었다. 같은 해 iPhone OS 3는 이 속성을 H/W 가속해서 60fps를 보장했고, **“GPU 가속 = transform·opacity만”**이라는 사실상 표준이 굳어졌다. 2014년 Paul Lewis가 정리한 FLIP 기법(First/Last/Invert/Play)은 이 제약을 우회하는 공학적 발견이었다 — 레이아웃이 바뀐 결과를 transform으로 역계산해 흉내 내자는 발상. 2023년 View Transitions API는 그 FLIP을 브라우저가 자동으로 해주는 흐름이다. Scroll-driven은 한 발 더 나아가, 시간조차 스크롤로 대체하자고 한다. 이 챕터는 그 30년 진화의 현재 시점 단면이다.


한 단락 요약

Motion은 Visual의 시간 미분이다. 보간(01·02) × 좌표(03) × 파이프라인(04) × 트리거(05·06) × 윤리(07)의 5축이 모이면, 우리는 *“왜 부드럽지 않을까”*를 *“렌더 파이프라인의 어느 단계가 막혔나”*로 디버깅할 수 있게 된다. 다음 챕터(07-responsive)는 이 모션이 다양한 화면 크기·컨텍스트에서 어떻게 적응하는지를 다룬다.