ゆろぐ

ゆるく、ろぐる。独学フロントエンドエンジニアの技術ブログ

【CSS】transitionのアニメーションがカクツクときの対処法について

平日更新を意地でも続けたい。でも納期に迫られている案件もある。そんな状態で頭を掻きむしりながらこの記事を書いています。

というわけで今日は初学者向けに簡単な内容だけど、意外に中級者以上の人でもハマりやすいアニメーションのカクツキ問題について僕なりの対処法を書いていきます。

↓の記事にも少しだけアニメーションのカクツキについて書いているのでよければどうぞ。

脳死状態でも使える「will-change」

もしCSSアニメーションをつけた時に各月がある場合、まずは脳死状態でも手軽に使える「will-change」プロパティを使ってみてください。

例えば、画像にマウスオーバーをしたときに画像を1.1倍にするアニメーションがカクツクのであれば、その画像要素に対して「will-change: transform;」と記述します。

transformの部分はleftやtopなどにも使えるので、ボタンアニメーションの時なんかは適切変更して使うのもOK。

ただし、あまり多用すると閲覧者のPCスペックに依存して動作が遅くなることがあるので、必要最低限のプロパティを指定してあげるようにしてください。

原則使うな「translate3D()」

少し古い記事などには、アニメーションがカクツク時の対処法として「transform: translate3D(0,0,0.01)」などをつけるようなことが書かれていることがあります。

これは3dでの変化を与えることで、パソコンのグラフィック処理をする脳みそ(GPUなど)を強制的に使わせることで、アニメーションをスムーズにさせようって魂胆です。

これ、先ほど説明したwill-changeで解決します。

translate3D()を使う記述だと必要以上の処理をPCにさせるので、スペックの低い端末だと処理の負荷が重すぎてしまうので、原則translate3D()は使わずにwill-changeで必要なプロパティだけを指定するようにしましょう。

borderのアニメーションは要注意

よくハマる事例として、borderの太さを変えるようなアニメーションが滑らかにいかないことがあります。

will-changeを使おうがtranslate3D()を使おうが解決しません。まるで底なし沼ですね。

解決方法としてはborderを変化させる要素を擬似要素や空divなどを使ってabsoluteにしてしまう方法です。

↑demo

デモのbox1が通常のborderでのアニメーション、box2が擬似要素を使ったアニメーションです。実際にマウスを乗せて試してみてください。

box1の場合、borderのサイズが変わるのに伴って周りの要素への影響もあったり、retinaディスプレイのような高解像の画面でないとカクツキが全体的に気になると思います。

box2は擬似要素を使っているのでアニメーションがあっても周りの要素への影響がありません。どちらを利用するかは案件によっても異なると思いますが、多くの場合後者(box2)の方が好まれる仕様になると思います。

余白系のアニメーションは代替しまくれ

実務案件で多いのアニメーションは余白や位置調整を含むアニメーションです。

サイズを大きくしても中央に残し続けたり、ホバーしたら少し右下に位置をずらす、スクロールに合わせてしたらか上に移動するなど。

ある程度CSSに触れているとわかるのですが、こういった余白や位置調整をする手段はいろいろな方法があります。

例えば下記のデモの場合、左から見て全て同じ位置にありますがそれぞれ指定の仕方が違います。

box1 marginを使った位置調整

box2 親要素にpaddingを使って位置調整

box3 transformを使って位置調整

box4 leftとrelativeを使って位置調整

box5 leftとabsoluteを使って位置調整

実際にはflex-boxを使ったりgridを使ったり、他にも方法はありますが、代表的な5つの例で作ってみました。

このboxにそれぞれホバーしたら左に5px移動するアニメーションをつけてみます。

それぞれのボックスにホバーしているとアニメーションが動きますが、見た目では同じように見えますよね。

cssのタブを見ていただければそれぞれ別の方法で移動しているのがわかると思います。

元々のmarginを50pxにして、ホバーすると45pxにすれば5px移動できますし、ホバーではtransform: translate(-5px,0);をつけることでも実装できます。left: -5px;でもいいかもしれませんし、親要素を使ってpadding-left: -5px;でも行ける場合もあると思います。

もしアニメーションがカクツクときはこのようにいろんな組み合わせを試してみるのも一つの手です。

特に親要素と子要素が別々にアニメーションするような場合など、少し複雑なアニメーションが必要な時には組み合わせ次第でカクツキを解消できることがあります。

1pxにご注意

retinaなどの高解像度ディスプレイやブラウザの仕様にもよりますが、1px以下の単位でのアニメーションはカクツキが起きたり画像が滲むようなことがあります。

例えば横幅101pxの要素に対して、transform: translate(-50%,0);を指定すると、左側に50.5px移動することになるので要注意ですね。

macユーザーでsafariを使っていると気づきにく現象ですが、通常のディスプレイでChromeなどを使ってみると結構違和感が出ることが多いです。

こういう時はデザインを変更してよければ101pxではなく102pxなど割り切れる数字にしてあげるだけでも改善します。

縦線を中心に引く際に、擬似要素でwidth: 1px;で作る場合に起きやすいので注意しましょう。←この場合は親要素をあえて101pxなどにすると、擬似要素の両サイドが50pxになるので綺麗に見えます。

まとめ

ホバー系のアニメーションはCSSで簡単に設定できる反面、アニメーションがカクツク時には対処法に困ってしまうこともよくあります。

特に複数の要素が同時にアニメーションする場合で、それぞれ依存関係があるともう泥沼。

できるだけシンプルな構造にしつつ、位置調整であれば代替手段がないかも検討する癖をつけるといいですね。

また、1px程度の変更であればデザインよりもスムーズに動くことを重視してディレクターやデザイナーに相談することもいいと思います!

【CSS】transitionのアニメーションがカクツクときの対処法について

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

トップへ戻る