keyframesアニメーションでdisplayプロパティが使えるようになる(なった)
Chromeのバージョン116で display
プロパティが @keyframes
アニメーションで使える有効なプロパティとなりました。
(content-visibility
も使えるようになりました。)
これまでdisplay
は指定しても無視されており、アニメーションの終了後に要素をdisplay: none
にしたい場合などはJavaScriptからクラスの付け替えなどを行っていましたが、Chromeでは@keyframes
だけで行えるようになりました。
そもそもなぜdisplayを使えなかったのか
Web Animationsの仕様(Working Draft)を見てみると、 Animating properties
という項目あります。
ここにはプロパティごとに「Animation Type」が設定されており、これに基づいてどうアニメーションするかが決まるとあります。このAnimation Typeには4つの種類があります。
- not animatable
- discrete
- by computed value
- repeatable list
それぞれのAnimation Typeがどういったアニメーションをするかは置いとくとして、注目したいのは not animatable
です。
このAnimation Typeが設定されているCSSプロパティは、@keyframes
内で出現した場合には単純に無視されるとあります。
displayプロパティのAnimation Typeを見てみる
もう推測はできていると思いますが、displayプロパティのAnimation Typeを見てみます。
Animation type: not animatable
https://www.w3.org/TR/css-display-3/#the-display-properties
not animatableということで、displayプロパティがアニメーションとして無視されるプロパティであることがわかります。
Chromeの実装が仕様と異なる?
displayプロパティがアニメーションできなかったのはWeb Animationsの仕様通りであることがわかりました。
ではなぜChromeだけが今になってdisplayプロパティをアニメーション可能なプロパティとして扱うようになったのか、Working Draftである現行の仕様に沿わないような変更を勝手に入れたのか(そんなことはしなさそうとは思いつつ)疑問に思ったので調べてみました。
CSS Display Module Level 4で変更あり
Display Moduleの次期標準候補であるCSS Display Module Level 4を見たところ、displayプロパティに変更が入ってるのがわかりました。
Animation type: see § 2.9 Animating and Interpolating display
https://drafts.csswg.org/css-display-4/#propdef-display
Level3では not animatable
であったAnimation Typeが Animating and Interpolating display
になっています。
(Animating and Interpolating display
は既存のAnimation Typeである discrete
の亜種のようなもの)
Chrome Platform Statusを探したところ、この機能を実装するモチベーションなどが書かれているものが見つかりました。
https://chromestatus.com/feature/5154958272364544
Specification
CSS Display Module Level 4
SpecとしてCSS Display Module Level 4を参照しています。このことからChromeが好き勝手にdisplayプロパティ(とcontent-visibility)をアニメーション可能にしたのではなく、次の仕様に合わせて先行実装として変更を加えたとわかりました。
おわり
すべてのブラウザで@keyframes
でdisplayプロパティが使えるようになるのはまだ先になりそうですが、実装がそろえばよりシンプルに @keyframes
での要素の表示・非表示のコントロールが行えるようになりそうです。
Discussion