【CSS/JS】displayとopacityを併せたアニメーション

記事
IT・テクノロジー
こんにちは。
最近はアニメーションはどこのサイトでも取り入れており、
必須の技術と感じますね。

アニメーションを実装する手段はGSAPなどのJSライブラリやCSSアニメーションなど様々ですが、僕はCSSアニメーションを主に使用しています。

そこで結構な頻度で実装するのが、
「要素のフェードイン・フェードアウト」ですね。

例えばポップアップやダイアログなどがそれに該当しますが、
ポップアップやダイアログは通常「非表示」にしておき、
なにかのきっかけで「表示」すると思うのですが、
その際に「アニメーションを付与する」となると実は結構ややこしかったりします。

表示非表示の制御は結構たくさんあります。例に上げると、
display
visibility
opacity
だいたいこの3つが代表じゃないかなと思います。

display以外の2つは、
「視覚的に表示非表示を切り替える」用途で使われており、
displayは「要素そのものの存在をON/OFFする」用途で使われています。

で、アニメーションでこの表示非表示を切り替えたい!となった時、
アニメーションが適用されるプロパティは「opacity」だけなんですね。

例えば、

transition: .5s;
opacity: 0;

表示非表示を切り替える要素にこのCSSを適用するとしましょう。
opacityが0なのでこのままだと要素は非表示の状態で、
opacityを1に設定すると、要素は表示状態になります。
そして、transition: .5s;を指定することによって、
「opacityが0から1へ変化する動作を0.5秒で行う」という設定になるわけです。

これでCSSアニメーションによる表示/非表示切り替えは出来るのですが、
ここで1つ問題があって、

opacityは「視覚的表示非表示を切り替えるだけであって、要素そのものは存在し続ける」

ということです。
つまり、画面には何も表示されてないのに、
「非表示になっている要素の領域が存在する」
という謎の状態になってしまいます。

多くの場合、
要素が非表示になっているときはその要素の領域も消えていてほしいものです。
その場合は「display」プロパティを使用するのですが、
displayプロパティにはちょっと厄介な問題があって

「transition」が効かなくなるんですね。

つまり、アニメーションではなく一瞬でopacityがチカチカと切り替わるようになってしまうのです。
一瞬で「イケてない」動きに劣化してしまうのですが、

display:none;
opacity:0;
transition: .5s;

どんなに頑張ってもこのコードではアニメーションは再現出来ません。

そこで私が行っている我流の手法を紹介します。


【対象の要素のCSS初期設定】
display:none;
opacity:0;
transition: .5s;

【処理の流れ】
1.要素のdisplayをblockにする
2.要素のopacityを1にする

この流れをJavaScriptで再現するだけになります。

        $('.youso').css('display','block'); 
        $('.youso').css('opacity', 1);

思わず上記のように書いてしまいがちなのですが、
ここで一つ問題があって、

通常の処理速度で上記を実行すると、display制御からopacity制御に移るまでが早すぎて、transitionが作動しません

つまり、display制御からopacity制御をするまでに、
1テンポ遅らせればdisplay制御とopacity制御が分離され、
transitionが効く状態でopacityの変更が可能になります。
$('.youso').css('display','block'); 
// setTimeoutで、10ミリ秒後に実行させる
setTimeout(function(){
    $('.youso').css('opacity', 1); 
},10);   
上記のように、10ミリ秒遅らせるだけで、
displayをblockにしたあと、opacityで要素の表示をアニメーション有りで行えるようになります。

長くなりましたが、以上で私の「ちょっと特殊なフェードイン・フェードアウト」の実装例紹介を終わりますm(_ _)m


サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す