モーション
トランスフォーム
Transform
トランスフォームとは、要素が実際に占める場所はそのままに、見た目だけを移動・拡大・回転させる機能です。
定義
トランスフォームは、要素が実際に占めている場所はそのままにして、見た目だけを動かしたり 大きくしたり回したりする機能です。代表的なものに、位置をずらす translate(移動)、 大きさを変える scale(拡大)、角度を変える rotate(回転)があります。ここで大事なのは 「本当の位置は動いていない」という点です。トランスフォームで要素を右にずらしても二倍に 拡大しても、隣にある要素は元の位置にじっとしたままです。つまり画面上は動いて見えても、 レイアウトの計算上は何も起きていないかのように扱われます。この性質のおかげで、 トランスフォームは動きをつけるときに一番よく使う道具になっています。
なぜ重要か
画面上の要素を動かす方法はトランスフォームだけではありません。left や top といった 位置のプロパティを変えても要素は移動します。ただしこのやり方だと、値を変えるたびに ブラウザがまわりの要素の位置まで計算し直すことになり、動きがカクついたり引っかかったりしがちです。 一方トランスフォームはレイアウトに手を加えず、主に GPU が絵だけを別に動かしてくれるため、 ずっと滑らかで軽く処理されます。だから実務の動きはほとんどトランスフォームで作ります。 たとえばカードにマウスを乗せたときにふわっと浮き上がる効果は translateY で少し上に持ち上げる ことですし、押された感じは scale でほんのわずかに縮めることです。処理が軽いので、 低スペックの端末やスマホでも安定して動き、どんな環境でも使い心地を守ってくれます。 動きを作るときにどのプロパティを変えるか迷ったら、まずトランスフォームで表現できないかを 先に思い浮かべる習慣をつけると、とても役に立ちます。
よくある間違い
- 動きを left や top で作ってしまうことです。止まった状態の位置調整には問題ありませんが、 この値をアニメーションで変え続けると画面がカクつきやすくなります。移動は translate で作る ほうが、たいていはずっと滑らかです。
- scale で要素を大きくしたあと、文字がぼやけるのを見落とすことです。トランスフォームは すでに描かれた絵を引き伸ばす方式なので、大きく拡大すると文字やアイコンがにじんで ぼんやり見えることがあります。
- トランスフォームをかける要素の基準点を気にしないことです。回転や拡大は、どの地点を 中心にするかで結果がまるで変わるので、意図と違う方向に飛び出してしまいがちです。
実務のヒント
- 動きはできるだけトランスフォームで作りましょう。特にホバーで少し上に浮く効果は translateY で、 押された感じはごく小さな scale で表現すると、left や top のような位置プロパティより はるかに滑らかで、性能も良くなります。移動と拡大が絡んだ複雑な動きほど、この差は大きく開きます。
- トランスフォームはたいていトランジションと組み合わせて使います。トランスフォームが 変化後のゴールの姿を決め、トランジションがその変化を時間をかけて滑らかにつなぐ、と考えると、 二つの役割がすっきり分かれます。
- 値はごく小さく始めましょう。ホバー時に translateY で数ピクセル持ち上げるだけでも十分に 浮いて見えますし、scale を 1 からほんの少しずらすと自然です。大きく拡大したり 回しすぎたりすると、ふざけた印象になりがちです。
AIに頼む
下に貼り付けるコードから、left・top・marginをアニメーションやトランジションで変化させて動かしている箇所を全部見つけて、同じ動きをtransform: translateで書き直して。位置プロパティを変えると、ブラウザが毎フレーム隣の要素の位置まで再計算してカクつくけど、translateはレイアウトに触れず、GPUが描画だけをずらすから、ずっと滑らかになるんだ。書き直したあと、隣の要素の位置がずれていないか確認して、箇所ごとに元のプロパティ→translateの対応と、変えた理由を表にまとめて。
[対象 — 例: 商品カード]にマウスを乗せると少し浮き上がり、押すと沈み込む、そんな細やかな反応をtransformで作って。浮き上がる感じはtranslateYで-2pxから-4pxだけ上に上げて、沈み込む感じはscaleで0.97くらいだけ少し縮めて — 1から大きく外れるとおもちゃっぽく見えてしまうから、値はごく小さく抑えて。left・topの代わりにtransformを使うと滑らかで性能もいいし、transformが目標の見た目を決め、transitionがその変化を時間をかけてつないでくれるように、二つを組み合わせて。
下のコードでrotateやscaleをかけたら、要素が意図した方向と違うほうへ飛んでいって、拡大した部分は文字がぼやけてにじむ。まずtransform-originの基準点がどこに設定されているか示して(初期値は要素の中心)、回転・拡大が狙った位置を中心に働くようにoriginを直して。それから、scaleで大きくした要素は、すでに描かれた絵を引き伸ばす仕組みだから、テキストやアイコンがぼやける。だから拡大ではなく、最初から大きいサイズ(フォントサイズや実際の寸法)で描くように変えて。