View Transitions

Baseline 2025画面の状態変化を、前後のスナップショットをつなぐアニメーションで表現するMDN ↗

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

使っている機能

document.startViewTransition()
コールバック内でDOMを変更すると、変更前後の画面をアニメーションでつなぐ
view-transition-name
要素に名前を付ける。変更前後で同じ名前の要素は、同じものとして位置と大きさが動く
view-transition-class
複数の要素にまとめてスタイルを当てるためのクラス名
::view-transition-group()
遷移中の要素を表す疑似要素。アニメーションの時間や速度の変化を指定する

CSS

.card {
	/* すべてのカードを "card" クラスとしてまとめて指定できるようにする */
	view-transition-class: card;
}

/* card クラスの付いた全要素のアニメーションを一括で指定する */
::view-transition-group(*.card) {
	animation-duration: 0.6s;
	animation-timing-function: cubic-bezier(0.3, 1.3, 0.6, 1);
}

JavaScript

// DOMの変更を startViewTransition() のコールバック内で行う
document.startViewTransition(() => {
	if (action === 'shuffle') list.append(...shuffle(cards));
	if (action === 'sort') list.append(...cards);
	if (action === 'filter') {
		cards.forEach((card, i) => {
			if (i % 2 === 0) card.hidden = !card.hidden;
		});
	}
});

HTML

<li class="card" style="view-transition-name: card-1; --hue: 20">1</li>
<li class="card" style="view-transition-name: card-2; --hue: 50">2</li>

使っている機能

view-transition-name
変更前はサムネイル、変更後は詳細の画像に同じ名前を付けると、2つの要素をつなげて動かせる
document.startViewTransition()
コールバック内でDOMを変更すると、変更前後の画面をアニメーションでつなぐ
::view-transition-group()
遷移中の要素を表す疑似要素。アニメーションの時間や速度の変化を指定する

CSS

.gallery-hero {
	/* 詳細側の画像。クリックしたサムネイルと同じ名前にして、つなげて動かす */
	view-transition-name: hero;
}

::view-transition-group(hero) {
	animation-duration: 0.5s;
	animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
}

JavaScript

// 変更前: クリックしたサムネイルに名前を付ける
thumb.style.viewTransitionName = 'hero';

document.startViewTransition(() => {
	// 変更後: 名前を詳細側の .gallery-hero に移す
	thumb.style.viewTransitionName = '';
	detail.style.setProperty('--hue', thumb.style.getPropertyValue('--hue'));
	detail.querySelector('.gallery-title').textContent = thumb.textContent;
	list.hidden = true;
	detail.hidden = false;
});