개요

View Transitions API는 페이지 전환 시 부드러운 애니메이션 효과를 브라우저 네이티브로 구현할 수 있게 해주는 웹 API입니다. SPA에서는 DOM 변경 시, MPA(Multi-Page Application)에서는 페이지 이동 시 사용할 수 있습니다.

기존에는 페이지 전환 애니메이션을 구현하려면 복잡한 JavaScript와 CSS 조합이 필요했지만, View Transitions API를 사용하면 브라우저가 자동으로 이전과 이후 상태의 스냅샷을 생성하고 전환 애니메이션을 적용합니다. 2025년 현재 SPA용 View Transitions는 모든 주요 브라우저에서 지원되며, MPA용도 Chrome에서 사용 가능합니다.

핵심 개념

View Transitions의 동작 원리를 이해하면 더 효과적으로 활용할 수 있습니다.

  • 스냅샷 기반: 브라우저가 전환 전후의 상태를 캡처하여 이미지 기반 애니메이션을 생성합니다.
  • view-transition-name: CSS 속성으로 전환에 참여할 요소를 지정합니다. 같은 이름의 요소끼리 연결됩니다.
  • ::view-transition 의사 요소: 전환 애니메이션을 커스터마이즈할 수 있는 의사 요소 트리가 생성됩니다.
  • document.startViewTransition(): SPA에서 DOM 변경을 감싸서 전환을 트리거합니다.
  • @view-transition: MPA에서 네비게이션 시 전환을 활성화하는 at-rule입니다.

실전 예제

블로그 목록에서 상세 페이지로 이동할 때의 View Transition 예제입니다.

/* 기본 페이지 전환 (페이드) */
@view-transition {
  navigation: auto;
}

/* 목록 페이지의 카드 썸네일 */
.post-card__thumbnail {
  view-transition-name: post-hero;
}

/* 상세 페이지의 히어로 이미지 */
.post-detail__hero {
  view-transition-name: post-hero;
}

/* 전환 커스터마이즈 */
::view-transition-old(post-hero) {
  animation: none;
}

::view-transition-new(post-hero) {
  animation: none;
}

::view-transition-group(post-hero) {
  animation-duration: 0.4s;
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

/* 페이지 콘텐츠 슬라이드 전환 */
::view-transition-old(root) {
  animation: slide-out 0.3s ease forwards;
}

::view-transition-new(root) {
  animation: slide-in 0.3s ease forwards;
}

@keyframes slide-out {
  to { opacity: 0; transform: translateX(-30px); }
}

@keyframes slide-in {
  from { opacity: 0; transform: translateX(30px); }
}

SPA(React, Next.js 등)에서의 활용 예제입니다.

<script>
// SPA에서 View Transition 사용
async function navigateTo(url) {
  // API 지원 확인
  if (!document.startViewTransition) {
    updateDOM(url);
    return;
  }

  const transition = document.startViewTransition(async () => {
    await updateDOM(url);
  });

  // 전환 완료 대기 (선택적)
  await transition.finished;
}

// 동적 view-transition-name 설정
function handleCardClick(postId) {
  const card = document.querySelector(`[data-post-id="${postId}"] img`);
  card.style.viewTransitionName = 'post-hero';
  navigateTo(`/posts/${postId}`);
}
</script>

활용 팁

  • view-transition-name은 고유해야 합니다. 같은 페이지에 동일한 이름이 두 개 이상 있으면 전환이 무시됩니다.
  • 동적 이름 할당: 목록의 여러 아이템 중 클릭된 것에만 view-transition-name을 동적으로 부여하는 패턴이 일반적입니다.
  • prefers-reduced-motion을 반드시 고려하세요. 접근성을 위해 모션을 줄이거나 비활성화하는 미디어 쿼리를 적용해야 합니다.
  • Next.js App Router에서는 useRouter와 결합하여 라우트 전환에 View Transitions를 적용할 수 있습니다.
  • 전환 시간은 200-400ms가 적당합니다. 너무 길면 사용자 경험이 저하됩니다.

마무리

View Transitions API는 웹 페이지 전환에 네이티브 앱 수준의 부드러움을 더해주는 강력한 기능입니다. SPA와 MPA 모두에서 사용할 수 있으며, CSS와 JavaScript의 최소한의 코드만으로 인상적인 전환 효과를 구현할 수 있습니다. 점진적 향상 방식으로 도입하여 사용자 경험을 한 단계 끌어올려 보시기 바랍니다.