目次
目次
はじめに
※ 本エントリは、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ツリー内で独立した要素としてキャプチャされ、遷移できる
本エントリでは、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ツリー内で独立した要素としてキャプチャされ、遷移できる
📝 視覚的には"要素単位での遷移"が可能
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
を要素の数だけ重複なく指定する必要があります。
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
- [css-view-transitions-2] view-transition-name determined by element · Issue #8320 · w3c/csswg-drafts
つまり、③の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):
📝 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.