View Transition

뷰 트랜지션

A native browser API that automatically cross-fades or morphs between the "before" and "after" states of a page or DOM change, via document.startViewTransition().

Also known as: View Transitions APIPage transition
···
html
<div class="screen" id="screen">
  <div class="avatar"></div>
  <div class="info"><b>Nova</b><span>Online</span></div>
</div>
css
.screen{position:relative;width:min(90%,460px);height:70%;display:flex;align-items:center;gap:16px;padding:0 6%}
.avatar{width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent-2));
  view-transition-name:avatar;flex:none}
.info{view-transition-name:info;display:grid;gap:4px}
.info b{font:700 16px/1 sans-serif;color:var(--fg)}
.info span{font:12px/1 sans-serif;color:var(--muted)}
.screen.detail{flex-direction:column;justify-content:center;text-align:center}
.screen.detail .avatar{width:96px;height:96px}
::view-transition-old(root),::view-transition-new(root){animation-duration:.5s}
js
const screen = document.getElementById('screen');
function toggle() {
  const apply = () => screen.classList.toggle('detail');
  if (document.startViewTransition) document.startViewTransition(apply);
  else apply();
}
setInterval(toggle, 2200);

The browser snapshots the state right before the change like a screenshot, lets the DOM update however you want, snapshots the new state, and automatically cross-fades between the two. Give two elements the same view-transition-name across the before/after states and the browser pairs and morphs them — position and size included — essentially doing FLIP's math for you.

Beyond SPA state changes, Chrome extended this API to full multi-page navigations between same-origin documents too.

The avatar below morphs position and size automatically, thanks to view-transition-name, every time the layout switches from a list row to a detail view.

When to use

Treat it as progressive enhancement based on browser support — if startViewTransition doesn't exist, fall back to an instant change.