Safari 18.2 「view-transition-name: auto;」への警鐘

2025-02-17

目次

目次

  1. はじめに
  2. Quick Wrap Up What view-transition-name Is & What's Desired
  3. view-transition-nameを自動生成する提案
  4. view-transition-name: auto;
  5. Allow an auto-generated view-transition-name that doesn't default to ID
  6. Safari 18.2でview-transition-name: auto;がShip
  7. Appendix

はじめに

※ 本エントリは、View Transition APIの知識を前提としています。View Transition APIの基本的な情報に関しては、こちらが参考になります。

View Transition APIは、DOM要素変更間でのシームレスなアニメーションを提供するAPIです。

このAPIを使用するにあたって、view-transition-nameプロパティを使用することがしばしばあります。view-transition-nameプロパティは、View Transitionされる要素に任意の名前(<custom-ident>)を指定することで要素を独立したものとしてキャプチャし、::view-transitionツリー内で独立した遷移要素として扱うためのCSS プロパティです。

::view-transitionツリー内で独立した要素としてキャプチャされ、遷移できる ::view-transitionツリー内で独立した要素としてキャプチャされ、遷移できる

本エントリでは、Safari 18.2でShipされたview-transition-name: auto;と、それを私たちがどう捉えるべきかについて述べます。

Quick Wrap Up What view-transition-name Is & What's Desired

view-transition-nameは、以下のようにCSSを適用することで、View Transition APIを使用する際に要素を独立したものとしてキャプチャし、遷移できるようにします。 これにより、視覚的には"要素単位での遷移"が可能となります。

::view-transitionツリー内で独立した要素としてキャプチャされ、遷移できる ::view-transitionツリー内で独立した要素としてキャプチャされ、遷移できる

📝 視覚的には"要素単位での遷移"が可能

DOM的な遷移単位は、あくまでも::view-transitionツリーです。DOM的にも遷移要素を独立させ、View Transitionの範囲(::view-transitionツリー)を任意の要素に限定して扱いたいという要望に対しては、Scoped View Transition が提案されています。

view-transition-nameの使用にあたって注意したいのが、view-transition-nameはDOMのid属性のように、View Transition内で一意である必要があるという点です。これは、遷移前のキャプチャ(::view-transition-old(<custom-ident>))と遷移後のキャプチャ(::view-transition-new(<custom-ident>))で同一のview-transition-nameを持つことで、遷移前後の要素を関連付けて遷移するためです。

view-transition-name重複時のエラー view-transition-name重複時のエラー

そのため、view-transition-nameを多くの要素に対して適用したい場合、以下のように、view-transition-nameを要素の数だけ重複なく指定する必要があります。

See the Pen View Transitions like IsotopeJS by Jake Archibald (@jaffathecake) on CodePen.

こうした問題を解決するために、view-transition-nameの自動生成が提案されています。

view-transition-nameを自動生成する提案

まず、自動生成に関するview-transition-nameの新たなキーワードは、「① HTML id属性を参照するもの」「② Elementの識別子を参照するもの」「③ id属性を参照できなかったら、Elementの識別子にフォールバックするもの」に大別して話が進められます。

RESOLVED: Add three keywords, one for ID attribute, one for element identity, and one that does fallback between the two. https://github.com/w3c/csswg-drafts/issues/8320#issuecomment-2344208387

そして、実際には、それぞれ以下のように実現される運びです。

① HTML id属性を参照するもの:attr(id ident)
② Elementの識別子を参照するもの:match-element
id属性を参照できなかったら、Elementの識別子にフォールバックするもの:auto

つまり、③のautoは①と②を組み合わせた、attr(id ident, match-element)のシンタックスシュガーのようなイメージです。

今回は、このautoが仕様的な問題を抱えたままWebKitに実装されたことが、議論の的となります。

view-transition-name: auto;

まず、執筆時点の仕様では、view-transition-name: auto;は、以下のような挙動をすることになっています。

To make this easier, setting the view-transition-name to auto would generate a view-transition-name for the element, or take it from the element’s id if present.

id属性が存在する場合はid属性を参照し、id属性が存在しない場合は、Elementの識別子を生成する

6. Determining view-transition-name automatically | CSS View Transitions Module Level 2

view-transition-name: auto;を使うと、これまで要素ごとにview-transition-nameを指定していたものが、HTMLのid属性を参照するか、フォールバックしてUAによって自動で生成されることになります。

<ul>
 <li>Item 1</li>
 <li>Item 2</li>
 <li>Item 3</li>
 <li>Item 4</li>
 ...
</ul>
<style>
/* これが */
li:nth-child(1) { view-transition-name: item1; }
li:nth-child(2) { view-transition-name: item2; }
li:nth-child(3) { view-transition-name: item3; }
li:nth-child(4) { view-transition-name: item4; }
...
 
/* こうなる */
li {
 view-transition-name: auto;
}
</style>

autoの実現には、フォールバック時に「Elementの識別子を生成する仕様」が追加で必要になります。それが、view-transition-name: match-element;です。そして、このmatch-elementの提案が、autoの懸念を浮き彫りにする議論へと発展します。

RESOLVED: [Pending async confirmation] auto will match elements using their ID attributes, falling back to element identity; match-element will only use element identity. https://github.com/w3c/csswg-drafts/issues/10995#issuecomment-2447567969

Allow an auto-generated view-transition-name that doesn't default to ID

match-elementにより、「id属性が存在する場合はid属性を参照し、id属性が存在しない場合は、Elementの識別子を生成する」というautoの挙動は再現できるかのように思えますが、アプリケーションによってはautoの挙動に差異が生じることになります。

Elementに対してIDを生成するmatch-elementは、ページ遷移でElementが全く別のものに挿し替わると、それぞれのElementに一意のIDを割り振ります。つまり、MPAのような、ページ遷移にサーバへのリクエストを伴うアプリケーションにおいては、match-elementではView Transitionができません。これは、Cross-Document View Transitionでは、autoが使えないことを意味します。

その反面、SPAのような、ページ遷移にサーバへのリクエストを伴わず、DOMの削除/追加によってページ遷移を擬似的に実現するアプリケーションにおいては、match-elementでのView Transitionは可能でしょう。

これらを踏まえると、view-transition-name: auto;は、「id属性が存在する場合はid属性を参照し、id属性が存在しない場合は、Elementの識別子を生成する」ことでview-transition-nameを自ら指定しなくてよくなる、という当初の目的に反した挙動の差異を生む可能性を孕んでいます。

  • HTML id属性が存在する場合:autoは動作する
  • HTML id属性が存在しない場合
    • SPA(Same-Document View Transition / Scoped View Transitions): match-elementが動作するので、autoは動作する
    • MPA(Cross-Document View Transition): match-elementが動作しないので、autoは動作しない

📝 SPA(Same-Document View Transition / Scoped View Transitions)

現在策定が進んでいるScoped View Transitionsは、Same-Document View Transitionに限定された機能のため、autoを用いたView Transitionが可能と表記しています。

もし、要素にid属性を持たせていたとしても、その要素の::before::afterなどの擬似要素にはid属性がないため、それらをCross-Document View Transitionしたい場合、autoは動作しません。

Same-Document View Transitionにおいては、一貫して動作しますが、Cross-Document View Transitionにおいては、一貫した動作が保証されない。こうしたmatch-elementの挙動差異をautoでというキーワードで握りつぶして提供することは、「autoは動く時もあるけど、動かない時もある」という最もデバッグしにくく、不安定な状態を生むことになりかねません。

Safari 18.2でview-transition-name: auto;がShip

View Transition APIは比較的新しい機能で、まだ十分に機能を理解して利用できている人も多くないのではと思います。

「要素数が多くても、view-transition-nameプロパティを自動で生成できますよ!」という提案のリリースノートは、view-transition-nameの扱いをシンプルにしてくれるものとして、非常に魅力的なものとして受け取る人も多いはずです。そんな中、文末の「if」の意味をきちんと理解し、「view-transition-name: auto;は、id属性を持たない要素のCross-Document View Transitionに対しては使えない」と咀嚼できる人はどれほどなのでしょうか。

WebKit for Safari 18.2 adds support for view-transition-name: auto. This means you won’t have to individually name potentially hundreds of different content items if you are applying transitions to the content on a single page.

WebKit Features in Safari 18.2 | WebKit

Appendix

Copyright © 2025 saku 🌸 All rights reserved.