View Transition Types

뷰 트랜지션 타입

Styles a view transition differently based on why it happened — slide left for "next", slide right for "back".

Also known as: active-view-transition-typeNamed view transitions
···
html
<div class="wrap">
  <div class="badge" id="badge"><svg viewBox="0 0 10 10"><path id="bpath" d="M1.5 5.2l2.6 2.6L8.5 2.4" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg><span id="btext">확인 중</span></div>
  <div class="stage" id="stage"><div class="slide" id="slide">1</div></div>
</div>
css
.wrap{position:relative;width:100%;height:100%;display:grid;place-items:center}
.stage{width:140px;height:70px;overflow:hidden;border:1px solid var(--line);border-radius:10px;position:relative}
.slide{position:absolute;inset:0;display:grid;place-items:center;font-size:24px;font-weight:800;color:var(--accent);background:var(--surface)}
::view-transition-old(root):active-view-transition-type(forward){ animation-name: out-left }
::view-transition-new(root):active-view-transition-type(forward){ animation-name: in-right }
::view-transition-old(root):active-view-transition-type(back){ animation-name: out-right }
::view-transition-new(root):active-view-transition-type(back){ animation-name: in-left }
@keyframes out-left{to{transform:translateX(-100%)}}
@keyframes in-right{from{transform:translateX(100%)}}
@keyframes out-right{to{transform:translateX(100%)}}
@keyframes in-left{from{transform:translateX(-100%)}}
.slide.fwd{animation:slide-fwd .4s ease}
.slide.bwd{animation:slide-bwd .4s ease}
@keyframes slide-fwd{from{transform:translateX(60px);opacity:0}to{transform:translateX(0);opacity:1}}
@keyframes slide-bwd{from{transform:translateX(-60px);opacity:0}to{transform:translateX(0);opacity:1}}
.badge{position:absolute;top:10px;right:10px;display:flex;align-items:center;gap:5px;padding:4px 9px;border-radius:999px;font-size:10px;font-weight:700;background:var(--bg);border:1px solid var(--line);color:var(--accent-3);z-index:2}
.badge.no{color:var(--accent-2)}
.badge svg{width:9px;height:9px}
js
const ok = !!document.startViewTransition && CSS.supports('selector(:active-view-transition-type(x))');
const b=document.getElementById('badge'),p=document.getElementById('bpath'),t=document.getElementById('btext');
b.classList.toggle('no', !ok);
p.setAttribute('d', ok ? 'M1.5 5.2l2.6 2.6L8.5 2.4' : 'M2 2l6 6M8 2l-6 6');
t.textContent = ok ? 'transition types 지원됨' : '미지원 · CSS 폴백';
const slide = document.getElementById('slide');
let n = 1, dir = 'forward';
function step(){
  n = dir === 'forward' ? n + 1 : n - 1;
  if (n > 4) { n = 4; dir = 'back'; } if (n < 1) { n = 1; dir = 'forward'; }
  const render = () => { slide.textContent = n; slide.className = 'slide ' + (dir === 'forward' ? 'fwd' : 'bwd'); };
  if (ok) document.startViewTransition({ update: render, types: [dir] });
  else render();
}
setInterval(step, 1400);

A plain view transition (see the View Transition entry) doesn't distinguish why it fired — it always plays the same cross-fade/morph. A carousel or step wizard where "next" should slide left and "back" should slide right needs a different animation per transition, and the old workaround was toggling a class on the body right before the transition.

Passing a types array, like `document.startViewTransition({ update, types: ["forward"] })`, gives the in-flight transition a CSS state named `:active-view-transition-type(forward)`. Targeting it with `::view-transition-group(*):active-view-transition-type(forward)` lets you assign different keyframes just for that state — directional transitions expressed through the standard API.

Check caniuse/MDN baseline for support. Where it's missing (or `startViewTransition` itself is absent), toggling a direction class on the container right before the transition and faking the slide with CSS transitions/keyframes is the fallback.

When to use

Carousels or step wizards where the transition animation needs to differ based on which direction you moved.