뷰 트랜지션 타입

View Transition Types

뷰 트랜지션을 "왜 일어났는지"에 따라 다르게 연출하는 기능. 다음 페이지는 슬라이드-왼쪽, 이전 페이지는 슬라이드-오른쪽처럼.

다른 이름: 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);

기본 뷰 트랜지션(view-transition 항목 참고)은 전환이 왜 일어났는지 구분하지 않고 항상 같은 크로스페이드/모프를 씁니다. "다음"을 누르면 왼쪽으로, "이전"을 누르면 오른쪽으로 슬라이드해야 하는 캐러셀이나 스텝 마법사에서는 트랜지션마다 다른 애니메이션이 필요했는데, 예전에는 전환 직전 body에 클래스를 붙였다 떼는 방식으로 임시 처리했습니다.

`document.startViewTransition({ update, types: ["forward"] })`처럼 타입 배열을 넘기면, 진행 중인 트랜지션에 `:active-view-transition-type(forward)`라는 CSS 상태가 생깁니다. `::view-transition-group(*):active-view-transition-type(forward)`로 그 상태만 골라 다른 keyframes를 줄 수 있어, 방향이 있는 전환을 표준 API로 표현합니다.

기본 지원은 caniuse/MDN baseline을 확인하세요. 미지원 브라우저(또는 startViewTransition 자체가 없는 경우)에서는 전환 직전 컨테이너에 방향 클래스를 붙이고 CSS transition/keyframes로 슬라이드를 흉내 내는 것이 대안입니다.

언제 쓰나

캐러셀·스텝 마법사처럼 "어느 방향으로 이동했는지"에 따라 전환 애니메이션이 달라져야 할 때.