View Transitions와 Next.js: 라이브러리 없이 페이지 애니메이션
View Transitions와 Next.js: 라이브러리 없이 페이지 애니메이션
View Transitions API는 그 트릭을 당신에게서 가져다 브라우저에게 줍니다. 두 개의 살아있는 DOM 트리를 유지하고 측정하는 대신, 브라우저가 이전 상태의 스냅샷을 찍고, DOM을 업데이트하고, 새 상태의 스냅샷을 찍고, 두 이미지 사이를 애니메이션합니다 — 컴포지터에서.
javascript
function navigate(update) {if (!document.startViewTransition) {update(); // 지원 없음: 그냥 업데이트, 애니메이션 없음return;}document.startViewTransition(() => update());}
css
::view-transition /* 전체 페이지를 덮는 오버레이 */::view-transition-group(name) /* 크기와 위치 애니메이션 */::view-transition-image-pair(name)::view-transition-old(name) /* "이전" 스냅샷 */::view-transition-new(name) /* "이후" 스냅샷 */
모든 사람을 놀라게 하는 것: 스냅샷은 사진이지 요소가 아님
::view-transition-old는 작게 렌더링된 이전 요소가 아닙니다. 그것의 정적 이미지입니다. <video>는 한 프레임에서 멈춥니다. 로딩 스피너는 회전을 멈춥니다. 200ms에서는 아무 상관이 없습니다. 1000ms에서는 명백합니다.
이름 지정: 전체 계약
css
.card-image {view-transition-name: hero;}::view-transition-group(hero) {animation-duration: 400ms;animation-timing-function: ease-in-out;}
엄격한 규칙: view-transition-name은 어느 시점에서나 문서에서 고유해야 합니다.
React 19.2와 Next.js 16: 하나의 컴포넌트
tsx
import { ViewTransition } from "react";import Image from "next/image";import Link from "next/link";export function ProjectCard({ project }) {return (<Link href={"/projects/" + project.slug}><ViewTransition name={"project-" + project.slug}><Image src={project.cover} alt={project.title} /></ViewTransition></Link>);}
share와 default="none"은 함께 사용해야 합니다. default="none"에 share prop 없이는 이름 있는 쌍이 조용히 모핑을 중단합니다.
방향: 사용자에게 어느 방향으로 갔는지 알려주기
tsx
<Link href="/projects/runvalis" transitionTypes={["nav-forward"]}>Runvalis</Link><ViewTransitionenter={{ "nav-forward": "slide-in", "nav-back": "slide-out", default: "none" }}exit={{ "nav-forward": "slide-out", "nav-back": "slide-in", default: "none" }}default="none"><main>{children}</main></ViewTransition>
프레임워크 없는 버전
css
@view-transition {navigation: auto;}
함정과 모범 사례
- 항상 점진적 향상으로 취급하세요.
- 슬로우 모션으로 디버깅하세요.
prefers-reduced-motion을 존중하세요.- 오버레이는 기본적으로 클릭을 소비합니다.
- 스냅샷은 메모리를 소비합니다.
- 헤더를 고정하세요.
- 뷰 트랜지션은 보조 기술에는 보이지 않습니다.
결론
View Transitions는 내비게이션에 적용된 동일한 논거입니다: FLIP을 직접 실행하는 대신, 두 상태를 연결하는 것을 선언하고 브라우저가 두 장의 사진에서 연결을 그리게 합니다.