CSSアニメーションでフェードイン・フェードアウトを実現するためにはopacityを使うのが一般的ですが、「要素の領域が残っちゃうからdisplay:none;でやりたい…」と思ったことがある方もいらっしゃるかと思います。
基本的に、displayってtransitionが効かないのでアニメーションさせることができないんですよね。
…と思いきや、できるようになったんです!本記事ではCSSの書き方を紹介してまいります。
さとみこれを夢見ていたコーダーさんは少なくないはず(感涙)
@starting-styleとは?
@starting-styleとは、アニメーションさせる要素にプロパティの開始値を定義するためのCSSのアットルールです。
通常、display: none; が指定されている要素にはトランジションが効きません。
そこで@starting-styleルールを使い、トランジション開始時の初期スタイルを定義することによって、diplay: none;が指定されていたとしても正しくトランジションを発火することができます。
これはdiplay: none;からアニメーションさせる要素には必須となります。
記法は二パターンありますが、ネストを使用したほうが簡潔に記述できるので、下記の『記法①(入れ子式)』を推奨します。
/* ================================
記法①(入れ子式)
================================ */
.example:hover {
/* トランジション後 */
@starting-style {
/* トランジション前 */
}
}
/* ================================
記法②(既存のアットルール式)
================================ */
@starting-style {
.example:hover {
/* トランジション前 */
}
}
.example:hover {
/* トランジション後 */
}opacityとdisplayのアニメーションコード比較
JSを使わないメガドロップダウンメニューで比較してみましょう。
【従来の書き方】opacity
見えなくするだけのopacityに加え、不可視かつアクセシビリティツリーからも削除されるvisibilityを併用することでメガドロップダウンを実現しています。
display: none;と異なるのは、visibility: hidden;だと表示領域が残ってしまうという点です。
※開発者ツール([F12])を使うと確認できます。
表示領域が残ると、レイアウトが無視されず要素の横幅/高さ分スペースが空いた状態になります。
.gnav_mega {
opacity: 0;
visibility: hidden;
transition: 0.3s;
}
.gnav--ul-li:hover .gnav_mega {
opacity: 1;
visibility: visible;
}opacity: 0;とvisibility: hidden;とdisplay: none;で異なる点をおさらいしましょう。
opacityの特徴
- トランジション対応
- 値を
0にしても、見えなくなっているだけなので表示領域は残る - アクセシビリティツリーやスクリーンリーダーに認識される
visibilityの特徴
- トランジション非対応
- 値を
hiddenあるいはcollapaseにしても表示領域は残る - アクセシビリティツリーやスクリーンリーダーに認識されない
displayの特徴
- トランジション非対応
- 値を
noneにすると表示領域が残らない - アクセシビリティツリーやスクリーンリーダーに認識されない
【新しい書き方】display
冒頭で解説した@starting-styleを使用し、display: none;でのアニメーションを実現したパターンです。opacityやwidthなどの補間可能プロパティと併用します。
上記で紹介した【従来の方法】とは異なり、こちらは表示領域が完全に消えます。
ここでもう一つの肝となるのが、transition-duration: allow-discrete;です。
下記のサンプルコードはtransitionのショートハンドなので、この後詳しく説明しますね。
.gnav--ul-li:hover .gnav_mega {
/* トランジション後 */
display: block;
opacity: 1;
/* トランジション前 */
@starting-style {
/* ここにdisplay:none;は書かない */
opacity: 0;
}
}
.gnav_mega {
display: none; /* ここにdisplay:none; */
opacity: 0; /* フェードアウト用 */
transition: opacity 0.3s, display 0.3s allow-discrete; /* allow-discreteでdisplayがトランジション可能に */
}transition-durationとは?
アニメーションの開始〜終了までの時間を定義するCSSプロパティです。allow-discreteを指定すると、displayなどの離散プロパティのトランジションを可能にします。
※離散プロパティは徐々に変化せず瞬時に切り替わります。
「離散プロパティ」とは?
値を補間できないプロパティのことです。
トランジションの効かないプロパティと考えると簡単です。
diplay: none;やvisibility: hidden;の要素をトランジションするには、次のいずれかを使用します。
allow-discrete値を持つtransition-behaviorプロパティallow-discrete値はtransitionのショートハンド
/* transitionショートハンド */
transition: opacity 0.3s ease-out, display 0.3s ease-out allow-discrete;上記のtransitionショートハンド例では、離散プロパティであるdisplayのみallow-discreteを適用しています。
他の値との衝突を防ぐために、allow-discreteが一番最後になっていることをしっかり確認しましょう!
| 補間可能プロパティ | color,opacity,width,height,font-size,margin,padding etc |
|---|---|
| 離散プロパティ | display,visibility,background-image,mix-blend-mode,mask-image etc |
対応ブラウザ
@starting-styleもtransition-duration: allow-discrete;も、デスクトップ・スマホのすべてのブラウザでサポートされています!
@starting-style


transition-duration


まとめ
いかがでしたでしょうか?
補間可能プロパティと違って少々記述がめんどくさいかもですが、CSSアニメーションの実装を続けていれば「知っていてよかった」と思う日が必ず来ます!
JSなしでアニメーションしたいときに役に立つかもしれませんね^^












コメント