next.jsanimasjonercss og layouts

View Transitions i Next.js: sideanimasjoner uten animasjonsbibliotek

View Transitions i Next.js: sideanimasjoner uten animasjonsbibliotek

I 2015 beskrev Paul Lewis en teknikk han kalte FLIP – First, Last, Invert, Play. View Transitions API tar det tricket fra deg og gir det til nettleseren. I stedet for å holde to levende DOM-trær og måle dem, fotograferer nettleseren den gamle tilstanden, lar DOM oppdateres, fotograferer den nye tilstanden og animerer mellom de to bildene – på kompositortråden.

javascript

function navigate(update) {
if (!document.startViewTransition) {
update(); // ingen støtte: bare oppdater, ingen animasjon
return;
}
document.startViewTransition(() => update());
}

css

::view-transition /* overlegget som dekker hele siden */
::view-transition-group(name) /* animerer størrelse og posisjon */
::view-transition-image-pair(name)
::view-transition-old(name) /* "før"-øyeblikksbildet */
::view-transition-new(name) /* "etter"-øyeblikksbildet */

Det som overrasker alle: et øyeblikksbilde er et fotografi, ikke et element

::view-transition-old er ikke det gamle elementet ditt, bare rendret mindre. Det er et statisk bilde av det. En <video> fryser på én frame. En spinner slutter å snurre. Ved 200ms spiller ingenting av det noen rolle. Ved 1000ms blir alt åpenbart.

Navngivning: hele kontrakten

css

.card-image {
view-transition-name: hero;
}
::view-transition-group(hero) {
animation-duration: 400ms;
animation-timing-function: ease-in-out;
}

Den harde regelen: et view-transition-name må være unikt i dokumentet til enhver tid.

React 19.2 og Next.js 16: én komponent

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 og default="none" må følges ad. Med default="none" og ingen share-prop slutter det navngitte paret stille med å morphe.

Retning: fortelle brukeren hvilken vei de gikk

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>

Versjonen uten noe rammeverk

css

@view-transition {
navigation: auto;
}

Fallgruver og beste praksis

  • Alltid behandle som progressiv forbedring.
  • Feilsøk i sakte film.
  • Respekter prefers-reduced-motion.
  • Overlegget spiser klikk som standard. ::view-transition { pointer-events: none } sett.
  • Øyeblikksbilder koster minne.
  • Forankre overskriften.
  • En view transition er usynlig for hjelpeteknologi.

Konklusjon

View Transitions er det samme argumentet brukt på navigasjon: i stedet for å kjøre FLIP for hånd, erklærer du hva som kobler to tilstander og lar nettleseren tegne forbindelsen fra to fotografier.