Next.jsאנימציותCSS ופריסות

View Transitions ו-Next.js: אנימציות דפים ללא ספרייה

View Transitions ו-Next.js: אנימציות דפים ללא ספרייה

View Transitions API לוקח את הטריק הזה ממך ונותן אותו לדפדפן. במקום לשמור שני עצי DOM חיים ולמדוד אותם, הדפדפן מצלם snapshot של המצב הישן, מאפשר ל-DOM להתעדכן, מצלם snapshot של המצב החדש, ומאניק בין שתי התמונות — על ה-compositor.

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) /* snapshot "לפני" */
::view-transition-new(name) /* snapshot "אחרי" */

מה שמפתיע את כולם: snapshot הוא תצלום, לא אלמנט

::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" וללא prop של share, הזוג הממוין מפסיק בשקט למורף.

כיוון: ספר למשתמש לאיזה כיוון הוא הלך

tsx

<Link href="/projects/runvalis" transitionTypes={["nav-forward"]}>
Runvalis
</Link>
<ViewTransition
enter={{ "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>

הגרסה ללא שום framework

css

@view-transition {
navigation: auto;
}

מלכודות ושיטות עבודה מומלצות

  • תמיד טפל כ-progressive enhancement.
  • Debug בתנועה איטית.
  • כבד את prefers-reduced-motion.
  • שכבת-העל אוכלת קליקים כברירת מחדל.
  • Snapshots צורכים זיכרון.
  • עגן את ה-header.
  • View transition אינו גלוי לטכנולוגיות עזר.

סיכום

View Transitions הוא אותו הטיעון המוחל על ניווט: במקום להריץ FLIP ידנית, אתה מצהיר מה מקשר שני מצבים ומאפשר לדפדפן לצייר את הקשר משתי תצלומים.