メインコンテンツに移動
CSSアニメーションとJavaScriptアニメーションの違い完全ガイド

CSSアニメーションとJavaScriptアニメーションの違い完全ガイド

CSSアニメーションとJavaScriptアニメーションは、どちらもWeb UIに動きを加えるための重要な手段です。ボタンを押したときの反応、カードのフェードイン、モーダルの表示、スクロールに合わせた演出、ドラッグ操作、ゲーム的な動きなど、現代のUIではアニメーションが体験の分かりやすさや気持ちよさに大きく関わります。ただし、CSSとJavaScriptは同じ「動き」を作れるように見えても、設計思想、実装方法、パフォーマンス特性、保守性が大きく異なります。

CSSは、ホバー、フェード、スライド、ボタンの反応、モーダルの表示切り替えなど、状態変化に合わせた軽量なアニメーションに向いています。一方、JavaScriptは、スクロール連動、ドラッグ操作、スワイプ、ゲーム的なリアルタイム演出、複雑なタイムライン制御、ユーザー入力やアプリ状態に応じて変化する動きに向いています。重要なのは、どちらが優れているかではなく、目的に応じて使い分けることです。

実務では、CSSだけで十分な場面にJavaScriptを使いすぎると、コードが重くなり、保守もしにくくなります。逆に、JavaScriptで制御すべき複雑な動きをCSSだけで無理に実装すると、状態管理が崩れたり、条件分岐が扱いにくくなったりします。ここでは、CSSアニメーションとJavaScriptアニメーションの違いを、仕組み、実装、パフォーマンス、UX、アクセシビリティ、ライブラリ選定、実務での判断基準まで体系的に整理します。

1. CSSアニメーションとは

CSSアニメーションとは、CSSのプロパティを使って要素の見た目を時間的に変化させる仕組みです。代表的な方法には、状態変化に反応するtransitionと、あらかじめ定義した流れに沿って動かすanimationがあります。CSSは、見た目に関するルールを宣言的に書けるため、ボタンのホバー、カードのフェード、モーダルの表示、メニューの展開など、UIの状態変化を表現するのに向いています。

CSSアニメーションの強みは、実装が比較的シンプルで、ブラウザの最適化を受けやすい点です。特にtransformopacityを使ったアニメーションは、レイアウト再計算を避けやすく、滑らかに動かしやすいです。一方で、複雑な条件分岐やユーザー入力に細かく追従する動きは苦手です。そのため、CSSアニメーションは「見た目の状態変化」を担当するものとして考えると、設計しやすくなります。

1.1 transitionanimation の違い

transitionは、ある状態から別の状態へ変化するときに、その変化を滑らかにするための仕組みです。たとえば、ボタンにマウスを乗せたときに色を変える、カードをホバーしたときに少し浮かせる、メニューを開いたときに透明度を変えるといった場面で使います。transitionは、開始状態と終了状態があり、その間をブラウザが補完してくれるため、単純な状態変化に向いています。

一方、animationは、@keyframesで動きの流れを定義し、時間軸に沿って複数の状態を変化させる仕組みです。ローディングスピナー、繰り返しの揺れ、フェードインしながら上に移動する表示演出、バナーのループ演出などに向いています。transitionは「状態が変わったときに滑らかにする」ための仕組みで、animationは「動きそのものを時間軸で定義する」ための仕組みと考えると分かりやすいです。

項目transitionanimation
主な用途状態変化を滑らかにする時間軸のある動きを作る
開始条件hover、class変更、状態変更など自動再生、class付与、指定タイミングなど
動きの複雑さ単純な変化に向く複数段階の動きに向く
繰り返し基本的には状態変化ごとinfiniteなどで繰り返し可能
ボタンホバー、カード浮き上がりローディング、ループ演出、登場アニメーション

このように、transitionanimationはどちらもCSSで動きを作る手段ですが、役割は異なります。実務では、ボタンやカードのようなUI状態の変化にはtransition、ローディングや繰り返し演出のような時間軸を持つ動きにはanimationを使うと整理しやすくなります。

1.2 UI状態変化との相性

CSSアニメーションは、UI状態変化との相性が非常に良いです。たとえば、ボタンのホバー、フォーカス、アクティブ、無効状態、モーダルの開閉、アコーディオンの展開、タブ切り替え、トースト通知の表示などは、状態に応じて見た目を変える処理です。このような場面では、JavaScriptで毎フレーム制御するよりも、CSSで状態ごとの見た目を定義し、クラスや属性の切り替えだけをJavaScriptで行う方がシンプルです。

特に大規模UIでは、アニメーションをCSS側に寄せることで、デザインルールとして管理しやすくなります。たとえば、全ボタンのホバー時間を150msに統一する、モーダル表示は200msでフェードする、トースト通知はtransformopacityだけで動かす、といったルールを作ると、UI全体の動きに一貫性が出ます。CSSアニメーションは、単なる装飾ではなく、状態変化を分かりやすく伝えるための設計要素です。

2. JavaScriptアニメーションとは

JavaScriptアニメーションとは、JavaScriptの処理によって要素の位置、サイズ、透明度、回転、進捗、描画状態などを制御するアニメーションです。CSSが宣言的に「どのように見えるか」を定義するのに対して、JavaScriptは「いつ、どの条件で、どの値を、どの順番で変えるか」を細かく制御できます。ユーザー入力、スクロール位置、ドラッグ距離、アプリの状態、データの変化に応じて動きを変えたい場合に強力です。

JavaScriptアニメーションは、複雑なUIやインタラクションに向いています。たとえば、スクロールに合わせて要素を動かす、ドラッグ中にリアルタイムで座標を更新する、ゲームのように毎フレーム位置を計算する、複数要素を順番に動かす、条件によって動きを分岐させるといった処理は、CSSだけでは扱いにくくなります。ただし、JavaScriptはメインスレッドで動く処理も多いため、書き方を間違えるとカクつきや入力遅延につながります。

2.1 処理として動きを制御する

JavaScriptアニメーションでは、動きを「スタイルの変化」ではなく「処理」として制御します。たとえば、現在の座標、目標座標、速度、経過時間、ユーザー入力、スクロール量、ドラッグ距離などを計算し、その結果を要素に反映します。これにより、CSSだけでは難しいリアルタイム性や条件分岐を持つ動きが作れます。

一方で、処理として動きを制御するということは、設計を誤ると負荷が増えやすいということでもあります。毎フレームDOMを読み書きしたり、重い計算をしたり、不要な再レンダリングを発生させたりすると、アニメーションはすぐにカクつきます。JavaScriptアニメーションでは、動きの自由度が高い分、処理負荷、更新頻度、DOM操作、レンダリングコストを意識する必要があります。

2.2 requestAnimationFrame の役割

requestAnimationFrameは、ブラウザの描画タイミングに合わせてJavaScriptの処理を実行するための仕組みです。アニメーションをsetIntervalsetTimeoutで無理に回すより、ブラウザの描画サイクルに合わせられるため、滑らかな更新を行いやすくなります。特に、Canvas、ゲーム的な演出、ドラッグ中の追従、スクロール連動の更新などでは重要です。

requestAnimationFrameを使うと、ブラウザが次に画面を描画する直前に処理を実行できます。そのため、毎フレームの位置計算や描画更新に向いています。ただし、requestAnimationFrameを使えば必ず軽くなるわけではありません。中で重い処理をすれば、フレーム落ちは発生します。重要なのは、描画タイミングに合わせることと、1フレーム内の処理を軽く保つことです。

2.3 状態・入力・時間を細かく扱える

JavaScriptアニメーションの大きな強みは、状態、入力、時間を細かく扱えることです。たとえば、ユーザーがどれくらいドラッグしたか、スクロール位置がどこにあるか、現在のアプリ状態が開いているのか閉じているのか、データが何件あるのか、前回の操作から何秒経過したのかなどをもとに、動きを変えられます。この柔軟性は、複雑なインタラクションを持つUIでは非常に重要です。

たとえば、ドラッグアンドドロップUIでは、ポインター位置、衝突判定、スクロール位置、ドロップ可能領域、プレビュー表示などをリアルタイムに扱う必要があります。これをCSSだけで完結させるのは難しく、JavaScriptによる状態管理と座標計算が必要になります。JavaScriptアニメーションは、見た目だけでなく、入力処理や状態遷移と深く関係する動きに向いています。

制御方法内容向いている場面
requestAnimationFrame描画タイミングに合わせて更新するリアルタイム移動、Canvas、ゲーム的表現
イベント駆動クリック、スクロール、ドラッグに反応する入力連動UI、メニュー、スワイプ
状態管理連動アプリ状態に応じて動きを変えるReactやVueのコンポーネントUI
タイムライン制御複数の動きを順番に制御する複雑な演出、ランディングページ
ライブラリ制御専用ライブラリで補間や物理演算を扱う高度なUIアニメーション、演出重視UI

JavaScriptアニメーションは、細かい制御が必要な場面で強力です。ただし、自由度が高いほど設計も複雑になるため、CSSで済む部分までJavaScript化しないことが重要です。

3. CSSとJavaScriptの基本的な違い

CSSアニメーションとJavaScriptアニメーションの最も大きな違いは、動きを「宣言する」のか「処理として制御する」のかです。CSSは、どのプロパティをどの時間で変化させるかを宣言します。JavaScriptは、条件、時間、入力、状態を見ながら、どの値をどう変えるかを命令的に制御します。この違いは、実装のしやすさ、保守性、パフォーマンス、チーム開発に大きく影響します。

基本的な考え方として、単純な見た目の変化はCSS、複雑な状態や入力に連動する動きはJavaScriptに任せると設計しやすくなります。たとえば、ボタンのホバーはCSSで十分ですが、ドラッグ中に要素が指に追従し、衝突判定によって配置候補が変わるUIはJavaScriptが必要です。どちらか一方に寄せるのではなく、役割を分けることが重要です。

3.1 宣言的に書くCSS

CSSは、見た目のルールを宣言的に書く仕組みです。「このクラスが付いたら透明度を変える」「ホバーしたら色を変える」「このアニメーションを300ミリ秒で実行する」といった形で、状態と見た目の関係を定義します。処理の順番を細かく書くというより、最終的にどう見えるべきかを記述するのがCSSの考え方です。

宣言的に書けるため、CSSアニメーションはデザインルールとして管理しやすいです。たとえば、ボタン、カード、モーダル、トースト、ドロップダウンなどのアニメーション時間やイージングを統一できます。大規模UIでは、動きのルールをCSS変数やデザイントークンとして管理すると、UI全体の一貫性を保ちやすくなります。

3.2 命令的に制御するJavaScript

JavaScriptは、処理の流れを命令的に書けます。「現在位置を取得する」「目標位置との差を計算する」「次のフレームで少し近づける」「ユーザーがドラッグをやめたら慣性をかける」といった形で、動きのロジックを細かく制御できます。この性質により、JavaScriptは複雑なインタラクションに向いています。

ただし、命令的に制御するほど、コードは複雑になりやすくなります。アニメーション処理、状態管理、イベント処理、DOM更新が混ざると、どこで何が起きているか分かりにくくなります。そのため、JavaScriptアニメーションでは、動きの責務を明確に分けることが重要です。入力処理、状態管理、描画更新を整理しておかないと、保守性が下がります。

3.3 単純な動きと複雑な動きの分岐

単純な動きとは、開始状態と終了状態が明確で、条件分岐が少ないアニメーションです。ホバーで色が変わる、モーダルがフェードインする、カードが少し浮く、メニューがスライド表示されるといった動きは、CSSに向いています。これらは、JavaScriptで毎フレーム制御する必要がありません。

複雑な動きとは、ユーザー入力、スクロール位置、ドラッグ距離、データ量、アプリ状態によって変化するアニメーションです。たとえば、スクロール量に合わせて要素が動く、ドラッグ中の位置に応じてドロップ先が変わる、複数の要素が条件によって順番に動くような場面です。このような場合は、JavaScriptで状態や時間を制御する方が自然です。

3.4 保守性の違い

CSSアニメーションは、見た目のルールとしてまとまりやすいため、デザインシステムやコンポーネント設計に組み込みやすいです。たとえば、すべてのボタンのホバー時間、モーダルの表示速度、トースト通知の動きを統一できます。保守性を高めるには、アニメーション時間、イージング、距離、透明度などをトークン化すると効果的です。

JavaScriptアニメーションは、ロジックと結びつくため、設計を誤ると保守が難しくなります。特に、イベント処理、状態管理、DOM更新、アニメーション制御が一つの関数に混ざると、変更時にバグが起きやすくなります。JavaScriptでアニメーションを書く場合は、アニメーション制御を関数化・コンポーネント化し、再利用できる形にすることが重要です。

3.5 実装コストの違い

CSSアニメーションは、単純な動きであれば実装コストが低いです。数行のCSSでホバーやフェードを作れるため、小さなUIフィードバックには非常に向いています。また、CSSだけで完結する場合、JavaScriptの状態管理を増やさずに済むため、コード量も抑えられます。

JavaScriptアニメーションは、複雑な制御ができる反面、実装コストが高くなりやすいです。イベント取得、座標計算、状態更新、描画タイミング、パフォーマンス対策を考える必要があります。ただし、複雑な動きをCSSだけで無理に実装するより、JavaScriptで明確に制御した方が結果的に保守しやすい場合もあります。

項目CSSアニメーションJavaScriptアニメーション
書き方宣言的命令的
得意分野状態変化、軽い演出入力連動、複雑な制御
実装コスト単純な動きでは低い複雑な動きでは必要
保守性デザインルール化しやすいロジック整理が必要
パフォーマンスブラウザ最適化を受けやすい書き方次第で重くなる
hover、fade、slidedrag、scroll、timeline、game

CSSとJavaScriptの違いは、単なる実装方法の違いではありません。UIの動きをどこで管理し、どの責務として扱うかの違いです。実務では、この責務分離が重要になります。

4. パフォーマンスの違い

アニメーションのパフォーマンスは、UXに直結します。動きがカクつく、入力が遅れる、スクロールが重くなる、画面遷移が引っかかると、ユーザーはすぐに違和感を覚えます。特にモバイル端末や低スペック端末では、少しの負荷でも体感品質が大きく下がります。

CSSとJavaScriptのどちらを使う場合でも、重要なのはブラウザのレンダリングの仕組みを理解することです。レイアウト計算、描画、合成のどこに負荷がかかるかを意識し、なるべくtransformopacityのような軽いプロパティを使うことが基本になります。

4.1 ブラウザの最適化を受けやすいCSS

CSSアニメーションは、ブラウザが最適化しやすい場合があります。特にtransformopacityを使ったアニメーションは、レイアウト再計算を避けやすく、合成レイヤー上で処理されることが多いため、滑らかに動かしやすいです。ホバー、フェード、スライド、モーダル表示などはCSSで実装すると軽く保ちやすくなります。

ただし、CSSなら何でも軽いわけではありません。widthheighttopleftmarginなどを頻繁に変えると、レイアウト再計算が発生し、重くなる可能性があります。CSSアニメーションでも、どのプロパティを動かすかが重要です。ブラウザが最適化しやすいプロパティを選ぶことで、パフォーマンスを安定させやすくなります。

4.2 JavaScriptは処理負荷に注意が必要

JavaScriptアニメーションは自由度が高い反面、処理負荷に注意が必要です。毎フレームの計算、DOMの読み取り、DOMの書き込み、ReactやVueの再レンダリング、大量要素の更新などが重なると、すぐにフレーム落ちが発生します。特に、スクロールやドラッグのように入力が連続する場面では、処理を軽く保つことが重要です。

JavaScriptでアニメーションを扱う場合は、requestAnimationFrameを使って描画タイミングを合わせる、DOM読み取りと書き込みを分ける、不要な再レンダリングを避ける、更新対象を最小化するなどの工夫が必要です。JavaScriptは強力ですが、重い処理を毎フレーム実行すると、CSSよりも簡単にカクつきます。

4.3 transformopacity が軽い理由

transformopacityが軽いと言われる理由は、これらがレイアウト全体の再計算を引き起こしにくいからです。transform: translate()で要素を移動しても、他の要素の配置は基本的に変わりません。opacityで透明度を変えても、要素のサイズや位置は変わりません。そのため、ブラウザは比較的効率よく描画できます。

一方、widthheightを変えると、周囲の要素の位置やサイズに影響する場合があります。topleftも、配置計算に関係するため、状況によっては負荷が高くなります。アニメーションでは、見た目として移動や拡大を表現したい場合でも、実際にはtransformを使って表現する方が安全です。

4.4 レイアウト再計算を避ける考え方

レイアウト再計算とは、ブラウザが要素の位置やサイズを再計算する処理です。アニメーション中にこれが頻繁に起きると、描画が重くなります。特に、大量の要素がある画面や、ネストが深いレイアウトでは、再計算のコストが大きくなりやすいです。

レイアウト再計算を避けるには、位置移動にはtransformを使う、サイズ変更を頻繁に行わない、DOMの読み取りと書き込みを同じタイミングで繰り返さない、アニメーション対象を限定するなどの工夫が必要です。アニメーションは見た目の問題に見えますが、実際にはブラウザのレイアウト処理と深く関係しています。

4.5 低スペック端末での違い

高性能なPCでは滑らかに見えるアニメーションでも、低スペック端末や古いスマートフォンではカクつくことがあります。特に、JavaScriptで大量の計算を行うアニメーション、重い影やぼかしを多用したCSS、複数要素の同時アニメーションは、端末性能によって差が出やすくなります。

実務では、開発環境の高性能PCだけで判断せず、モバイル端末や低速環境でも確認することが重要です。アニメーションは、動けばよいのではなく、幅広い環境で快適に動く必要があります。パフォーマンスに不安がある場合は、まずCSSで軽く表現できる部分をCSSに任せ、JavaScriptで制御する部分を最小限にすると安定しやすくなります。

項目CSSアニメーションJavaScriptアニメーション
軽くしやすい場面transformopacity中心の状態変化更新対象が少ない入力連動
重くなりやすい場面widthheighttopleftの多用毎フレームの重い計算や大量DOM更新
ブラウザ最適化受けやすい実装次第
入力連動単純なものは可能複雑な制御に強い
低スペック端末軽量に保ちやすい負荷管理が重要
注意点動かすプロパティを選ぶフレームごとの処理を軽くする

パフォーマンスを考えるときは、CSSかJavaScriptかだけで判断するのではなく、何を動かしているのか、どれくらい頻繁に更新しているのか、どの端末で動かすのかを見る必要があります。

5. CSSアニメーションが向いている場面

CSSアニメーションは、UIの状態変化を軽く、分かりやすく表現する場面に向いています。ホバー、フォーカス、押下、表示、非表示、フェード、スライド、ローディングなど、見た目の変化が中心で、複雑な条件分岐が少ない場合はCSSで十分なことが多いです。CSSで実装することで、デザインルールとして管理しやすく、JavaScriptの処理も増やさずに済みます。

特に、UIの基本的なフィードバックはCSSで統一すると、体験が安定します。ボタンを押したときの反応、カードにホバーしたときの浮き上がり、モーダルの表示、トースト通知の登場などは、アプリ全体で一貫した動きにすることが大切です。CSSアニメーションは、こうした共通UIの動きに向いています。

5.1 ホバー演出

ホバー演出は、CSSアニメーションが最も得意とする場面の一つです。ボタンにマウスを乗せたときに色を変える、カードを少し浮かせる、リンクに下線を出す、アイコンを少し動かすなど、状態変化に合わせた軽い演出はCSSでシンプルに実装できます。JavaScriptで制御する必要はほとんどありません。

ホバー演出では、動きの強さを控えめにすることが重要です。大きく揺れたり、長く動いたりすると、操作の邪魔になります。ホバーは「押せる」「反応している」と伝えるための補助であり、主役ではありません。transitionを使って短時間で自然に変化させると、UIの操作感が良くなります。

5.2 ボタンの押下フィードバック

ボタンの押下フィードバックは、ユーザーに「押したこと」を伝えるために重要です。ボタンを少し沈ませる、色を変える、影を小さくする、透明度を変えるなどの反応があると、ユーザーは操作が受け付けられたと感じやすくなります。このような短い状態変化はCSSに向いています。

押下フィードバックがないと、ユーザーは本当に押せたのか不安になります。特にモバイルでは、タップ時の反応が重要です。ただし、押下演出が長すぎると操作が遅く感じられます。ボタンのフィードバックは、短く、軽く、即時に返すことが大切です。

5.3 フェードイン・フェードアウト

フェードイン・フェードアウトは、要素の表示や非表示を自然に見せるためによく使われます。モーダル、トースト通知、ドロップダウン、ツールチップ、画像表示などで、突然表示されるよりも、少し透明度を変化させた方が自然に感じられます。opacityは比較的軽いプロパティなので、CSSで扱いやすいです。

フェードは、状態変化を柔らかく伝えるための演出です。ただし、すべての表示切り替えに長いフェードを入れると、UIが遅く感じられます。重要なのは、ユーザーの理解を助ける範囲で使うことです。短時間のフェードであれば、画面の変化を自然に見せながら、操作感を損ないにくくなります。

5.4 スライド表示

スライド表示は、メニュー、パネル、ドロワー、アコーディオン、通知などでよく使われます。要素がどこから出てきたのかを示せるため、画面構造を理解しやすくなります。CSSでは、transform: translateX()translateY()を使うと、軽くスライド表現を作りやすくなります。

スライド表示では、topleftを頻繁に変えるより、transformを使う方がパフォーマンス的に安定しやすくなります。また、スライド距離が大きすぎたり、速度が遅すぎたりすると、操作の邪魔になります。ユーザーが状態変化を理解できる程度の短い動きにすることが重要です。

5.5 ローディング演出

ローディング演出は、処理中であることをユーザーに伝えるためのアニメーションです。スピナー、プログレスバー、スケルトン表示、点滅表現などがあります。単純なスピナーや繰り返しの動きは、CSSの@keyframesで実装しやすいです。

ただし、ローディング演出は待ち時間をごまかすためだけに使うものではありません。ユーザーに「処理が進んでいる」「もう少し待てばよい」と伝えるためのフィードバックです。短い待ち時間なら軽いスピナーで十分ですが、長い処理では進捗や説明を表示した方が安心感があります。

5.6 モーダルの表示切り替え

モーダルの表示切り替えでは、背景のフェード、モーダル本体のスケールやスライド、透明度の変化がよく使われます。これらはCSSアニメーションと相性が良い場面です。JavaScriptは開閉状態やフォーカス管理を担当し、見た目の動きはCSSに任せると設計が整理されます。

モーダルでは、アニメーションだけでなく、操作不能時間やアクセシビリティにも注意が必要です。表示アニメーションが長すぎると、ユーザーは待たされているように感じます。閉じる動きも同様に、短く自然にすることが重要です。モーダルは重要なUIなので、動きは分かりやすく、過剰にしない方が安定します。

CSS向きの場面理由実装の方向
ホバー演出状態変化が単純transition
ボタン押下即時フィードバックが必要transformbox-shadow
フェード表示切り替えが自然になるopacity
スライドパネル表示に向くtransform
ローディング繰り返し演出に向く@keyframes
モーダル表示状態変化と相性が良いclass切り替え + CSS

CSSアニメーションは、UIの基本的な反応を軽く統一するために非常に有効です。まずCSSで実装できるかを考え、必要な場合だけJavaScriptを使うと設計が安定します。

6. JavaScriptアニメーションが向いている場面

JavaScriptアニメーションは、ユーザー入力やアプリ状態と強く連動する動きに向いています。スクロール位置によって変化する演出、ドラッグ中の要素追従、スワイプ操作、ゲーム的なリアルタイム描画、複数要素の複雑なタイムライン、条件分岐を含むアニメーションなどは、CSSだけでは制御しにくい場面です。

JavaScriptを使うべきかどうかは、「動きが状態や入力に依存しているか」で判断すると分かりやすくなります。単に表示・非表示を滑らかにするだけならCSSで十分ですが、ユーザーの操作量やデータによって動きが変わるならJavaScriptが必要になります。

6.1 スクロール連動アニメーション

スクロール連動アニメーションは、ユーザーのスクロール位置に応じて要素を動かしたり、表示したり、進捗を変えたりする演出です。ランディングページ、ストーリーテリング型サイト、データ可視化、パララックス演出などで使われます。スクロール量に応じて動きを細かく変えるため、JavaScriptによる制御が必要になる場面が多いです。

ただし、スクロール連動は負荷が高くなりやすいので注意が必要です。スクロールイベントごとに重い処理を実行すると、スクロール自体がカクつきます。requestAnimationFrameで更新を調整したり、IntersectionObserverを使って必要なタイミングだけ発火させたりすると、パフォーマンスを保ちやすくなります。

6.2 ドラッグ・スワイプ操作

ドラッグやスワイプは、ユーザーの入力にリアルタイムで追従する必要があります。ポインター位置、移動距離、速度、方向、ドロップ候補、スクロールとの競合など、多くの情報を扱います。そのため、CSSだけで完結するのは難しく、JavaScriptによる座標計算や状態管理が必要です。

ドラッグやスワイプでは、入力遅延がすぐに違和感になります。要素が指やカーソルに遅れてついてくると、操作感が悪くなります。JavaScriptで制御する場合は、更新対象を最小限にし、transformで移動させ、不要な再レンダリングを避けることが重要です。入力連動アニメーションは、自由度よりも反応速度が重要です。

6.3 ゲーム的なリアルタイム演出

ゲーム的なリアルタイム演出では、毎フレーム位置、速度、当たり判定、状態、エフェクトを更新する必要があります。キャラクター移動、パーティクル、スコア演出、物理的な動き、Canvas描画などは、JavaScriptの制御が必要です。CSSのtransitionkeyframesだけでは、リアルタイムな状態変化に対応しにくくなります。

ただし、ゲーム的な演出は処理負荷が高くなりやすいため、パフォーマンス設計が重要です。描画対象を減らす、不要なDOM更新を避ける、CanvasやWebGLを使う、フレームごとの計算を最適化するなどの工夫が必要です。ゲーム的なUIをWeb上で作る場合は、アニメーションというよりリアルタイムレンダリングに近い考え方が必要になります。

6.4 複雑なタイムライン制御

複雑なタイムライン制御とは、複数の要素を順番に動かしたり、途中で停止・再開したり、ユーザー操作によって流れを分岐させたりするアニメーションです。ランディングページの演出、チュートリアル、プレゼンテーション風UI、オンボーディングなどで使われます。このような場合、CSSだけで管理すると、タイミングや依存関係が複雑になりがちです。

JavaScriptや専用ライブラリを使うと、タイムラインを明示的に管理できます。どの要素を何秒後に動かすか、前の動きが終わったら次を開始するか、ユーザー操作でスキップできるかなどを制御しやすくなります。複雑な演出では、CSSのアニメーション定義だけに頼るより、JavaScriptで流れを管理した方が保守しやすい場合があります。

6.5 条件分岐を含むアニメーション

条件分岐を含むアニメーションでは、ユーザーの状態やデータに応じて動きを変えます。たとえば、成功時と失敗時で演出を変える、ユーザーのレベルに応じて報酬アニメーションを変える、データ量に応じてグラフの動きを変える、入力値に応じてプレビューを変えるといった場面です。こうした条件分岐はJavaScriptが得意です。

CSSでもクラスを分ければある程度対応できますが、条件が増えると管理が難しくなります。JavaScriptで状態を判定し、CSSクラスやCSS変数を切り替える設計にすると、見た目とロジックを分離できます。条件分岐を含む動きでは、JavaScriptですべての見た目を直接制御するのではなく、状態判定をJavaScript、表現をCSSに分ける方法も有効です。

6.6 データに応じて変化する動き

データに応じて変化する動きとは、表示するデータの数値、量、変化に合わせてアニメーションが変わるものです。グラフの更新、進捗バー、ランキング変動、スコア表示、AI推薦結果の変化、学習進捗の可視化などが該当します。データによって開始値や終了値が変わるため、JavaScriptで値を計算する必要があります。

このような場面では、JavaScriptでデータを処理し、CSS変数やスタイルに値を渡す設計が便利です。たとえば、進捗率をJavaScriptで計算し、CSS変数--progressとして渡して、表示はCSSで制御する方法です。データと表現を分けることで、動きの柔軟性と保守性を両立しやすくなります。

JavaScript向きの場面理由実装の方向
スクロール連動スクロール位置に応じて動くrequestAnimationFrameIntersectionObserver
ドラッグ・スワイプ入力にリアルタイム追従するpointerイベント + transform
ゲーム的演出毎フレーム計算が必要Canvas・WebGL・requestAnimationFrame
複雑なタイムライン順番や分岐を管理するライブラリや状態管理
条件分岐状態に応じて動きを変えるJavaScriptで判定
データ連動数値に応じて変化するデータ計算 + CSS変数

JavaScriptアニメーションは、複雑な制御が必要な場面で非常に強力です。ただし、CSSで済む動きまでJavaScriptで制御すると重くなりやすいため、役割分担を意識する必要があります。

7. UIアニメーション設計の基本

UIアニメーションは、単に画面を華やかにするためのものではありません。ユーザーに状態変化を伝える、注意を誘導する、操作結果をフィードバックする、画面遷移を自然に見せる、読み込み中の不安を下げるなど、明確な目的を持つべきです。目的のないアニメーションは、ユーザーにとってノイズになります。

良いUIアニメーションは、ユーザーの理解を助けます。どこから要素が出てきたのか、どの操作が成功したのか、次にどこを見ればよいのかが分かりやすくなります。一方、過剰な動きや長すぎる演出は、操作を遅く感じさせたり、視覚疲労を生んだりします。UIアニメーションでは、気持ちよさと分かりやすさのバランスが重要です。

7.1 動きには目的を持たせる

UIアニメーションを入れるときは、その動きが何のためにあるのかを明確にする必要があります。単に「おしゃれだから」「目立つから」という理由で動きを入れると、体験を邪魔する可能性があります。動きは、状態変化、注意誘導、操作結果、進捗、階層関係などを伝えるために使うべきです。

たとえば、モーダルがフェードインすることで、画面の上に新しいレイヤーが出たことを理解しやすくなります。ボタンが押された瞬間に少し沈むことで、操作が受け付けられたことが伝わります。動きに目的がある場合、アニメーションはUXを強化します。目的がない場合、ただの装飾になりやすくなります。

7.2 注意誘導として使う

アニメーションは、ユーザーの視線を誘導するために使えます。新しい通知、エラー、完了メッセージ、次に押すべきボタンなどに軽い動きを加えると、ユーザーは重要な変化に気づきやすくなります。静的な画面では見落とされやすい情報も、短い動きによって認識されやすくなります。

ただし、注意誘導としてのアニメーションは使いすぎると逆効果です。画面内の複数要素が同時に動くと、どこを見ればよいか分からなくなります。注意誘導は、最も重要な変化に限定することが大切です。動きを使うほど目立つのではなく、動く要素が少ないからこそ目立ちます。

7.3 状態変化を分かりやすくする

UIでは、状態が変わったことをユーザーに伝える必要があります。メニューが開いた、モーダルが表示された、保存が完了した、エラーが発生した、項目が追加された、カードが並び替わったなど、状態変化は多くの場面で発生します。アニメーションを使うと、その変化が突然ではなく自然に見えるようになります。

状態変化を分かりやすくするには、動きの方向や流れにも意味を持たせることが重要です。横から出るメニューは横方向の階層を示し、下から出るシートは一時的な操作パネルとして理解されやすくなります。状態変化のアニメーションは、見た目の演出だけでなく、UI構造を理解させる役割を持ちます。

7.4 操作結果をフィードバックする

操作結果をフィードバックするアニメーションは、ユーザーの安心感に直結します。ボタンを押した後に反応がないと、ユーザーは押せたのか分からず、何度もクリックしてしまうことがあります。保存、送信、購入、削除、追加などの重要な操作では、即時フィードバックが必要です。

フィードバックは大きな演出である必要はありません。ボタンの押下、ローディング表示、完了チェック、トースト通知、軽い色変化だけでも十分な場合があります。重要なのは、ユーザーの行動に対してすぐに反応を返すことです。操作結果が見えると、ユーザーは安心して次の行動へ進めます。

7.5 画面遷移を自然に見せる

画面遷移のアニメーションは、ユーザーに画面の変化を理解させるために使えます。ページが突然切り替わると、文脈が途切れたように感じる場合があります。軽いフェードやスライドを使うことで、前の画面から次の画面へ自然に移ったように見せられます。

ただし、画面遷移アニメーションは長すぎると操作を遅く感じさせます。ユーザーは演出を見るためではなく、目的を達成するために操作しています。画面遷移の動きは短く、意味があり、操作を邪魔しないことが重要です。特に頻繁に使う画面では、長い演出は避けるべきです。

7.6 過剰な演出を避ける

過剰な演出は、UXを悪化させます。意味のない揺れ、回転、拡大縮小、長いフェード、派手な連続アニメーションは、最初は目を引いても、使い続けると疲れます。特に業務アプリや学習アプリでは、ユーザーは集中したいので、過剰な演出は邪魔になります。

アニメーションは、少ないほど効果的な場合があります。重要な状態変化、操作結果、注意誘導に絞って使うことで、動きの意味が強くなります。UIアニメーションの目的は、驚かせることではなく、分かりやすく、気持ちよく、迷わず操作できる状態を作ることです。

8. 実装方法の違い

CSSアニメーションとJavaScriptアニメーションには、複数の実装方法があります。CSSではtransition@keyframesが基本で、JavaScriptではrequestAnimationFrame、Web Animations API、アニメーションライブラリ、フレームワーク内の状態制御などが使われます。どの方法を選ぶかによって、実装コスト、保守性、表現力、パフォーマンスが変わります。

実務では、最初からライブラリを使うのではなく、まずCSSで十分かを確認することが大切です。CSSで表現できる単純な状態変化ならCSSを使い、複雑なタイムラインや入力連動が必要な場合にJavaScriptやライブラリを検討します。実装方法は、動きの複雑さとチームの運用方針に合わせて選ぶ必要があります。

8.1 CSS transition

CSS transitionは、状態変化を滑らかにするための基本的な方法です。ホバー、フォーカス、クラス付与、属性変更などでスタイルが変わるとき、その変化を指定した時間で補完できます。ボタン、カード、リンク、メニューなど、日常的なUIフィードバックに向いています。

transitionは実装が簡単で、保守もしやすいです。動きが単純であれば、JavaScriptで制御するよりもCSSだけで完結させた方が安全です。特に、デザインシステム内で共通のホバーや押下フィードバックを作る場合、transitionは最も扱いやすい方法です。

使用言語:CSS

ファイル名:button.css

.button {  transform: translateY(0);  opacity: 1;  transition: transform 160ms ease, opacity 160ms ease; } .button:hover {  transform: translateY(-2px);  opacity: 0.92; } .button:active {  transform: translateY(1px); }

この例では、ボタンのホバーと押下をCSSだけで表現しています。単純な状態変化なので、JavaScriptを使う必要はありません。

8.2 CSS keyframes

CSS keyframesは、時間軸に沿った動きを定義する方法です。ローディングスピナー、登場アニメーション、繰り返しのパルス、軽い揺れなどに向いています。transitionが状態変化に反応する仕組みであるのに対して、keyframesはアニメーションの流れそのものを定義します。

keyframesを使う場合は、繰り返しや時間の長さに注意が必要です。無限ループのアニメーションは、画面上に多すぎると視覚疲労やパフォーマンス低下につながります。ローディングや注意喚起のように、必要な場面に絞って使うことが重要です。

使用言語:CSS

ファイル名:loading.css

.loader {  width: 24px;  height: 24px;  border: 3px solid currentColor;  border-top-color: transparent;  border-radius: 50%;  animation: spin 800ms linear infinite; } @keyframes spin {  to {    transform: rotate(360deg);  } }

この例では、CSSだけでスピナーを実装しています。繰り返しの単純なローディング演出は、CSS keyframesに向いています。

8.3 JavaScript requestAnimationFrame

requestAnimationFrameは、JavaScriptで毎フレームの更新を行うための方法です。ブラウザの描画タイミングに合わせて処理を実行できるため、リアルタイムな動きに向いています。スクロール連動、ドラッグ、Canvas描画、ゲーム的な演出などで使われます。

ただし、requestAnimationFrameを使う場合は、1フレーム内の処理を軽く保つ必要があります。中で重い計算や大量のDOM更新を行うと、フレーム落ちが発生します。更新する値を最小限にし、transformなど軽いプロパティを使うことが重要です。

使用言語:JavaScript

ファイル名:follow-pointer.js

const box = document.querySelector(".box"); let targetX = 0; let currentX = 0; window.addEventListener("pointermove", (event) => {  targetX = event.clientX; }); function animate() {  currentX += (targetX - currentX) * 0.12;  box.style.transform = `translateX(${currentX}px)`;  requestAnimationFrame(animate); } animate();

この例では、ポインター位置に要素が滑らかに追従します。ユーザー入力に応じて毎フレーム値を更新するため、JavaScriptが向いています。

8.4 Web Animations API

Web Animations APIは、JavaScriptからブラウザ標準のアニメーション機能を扱う方法です。CSSのkeyframesに近い考え方をJavaScript側から制御でき、再生、停止、反転、速度変更などを扱えます。CSSとJavaScriptの中間的な選択肢として使えます。

Web Animations APIは、CSSだけでは制御しにくいが、毎フレーム自分で計算するほどではない場面に向いています。たとえば、クリック時に一時的な演出を実行する、条件に応じてアニメーションを再生する、ユーザー操作で停止・再開する場合に便利です。

使用言語:JavaScript

ファイル名:web-animation.js

const card = document.querySelector(".card"); card.addEventListener("click", () => {  card.animate(    [      { transform: "scale(1)", opacity: 1 },      { transform: "scale(1.04)", opacity: 0.9 },      { transform: "scale(1)", opacity: 1 }    ],    {      duration: 260,      easing: "ease-out"    }  ); });

この例では、クリック時にJavaScriptから一時的なアニメーションを再生しています。CSSクラスを増やさず、必要なタイミングで動きを実行できます。

8.5 アニメーションライブラリ

アニメーションライブラリは、複雑な動きや高度なタイムライン制御を簡単に扱うために使います。Framer Motion、GSAP、Anime.js、Lottieなどが代表的です。複数要素の順番制御、物理的な動き、複雑なイージング、SVGアニメーション、Reactコンポーネントとの連携などに向いています。

ただし、ライブラリを使うとバンドルサイズや学習コストが増える場合があります。単純なホバーやフェードのために大きなライブラリを導入するのは過剰です。ライブラリは、CSSや標準APIでは保守しにくい複雑な演出がある場合に検討するのが現実的です。

8.6 フレームワーク内での制御

ReactやVueなどのフレームワークでは、状態管理とアニメーションが密接に関係します。たとえば、isOpentrueになったらモーダルを表示し、falseになったら閉じるといった形です。この場合、JavaScriptは状態の切り替えを担当し、見た目のアニメーションはCSSやライブラリに任せる設計がよく使われます。

フレームワーク内でアニメーションを扱う場合は、状態と演出がズレないようにすることが重要です。DOMから消えるタイミングが早すぎると、閉じるアニメーションが再生されません。逆に、状態管理が複雑になると、表示されていないはずの要素が残ることもあります。状態遷移とアニメーションの終了タイミングを整理する必要があります。

実装方法特徴向いている場面
CSS transition状態変化を滑らかにするhover、focus、表示切替
CSS keyframes時間軸の動きを定義するローディング、登場演出
requestAnimationFrame毎フレーム制御するドラッグ、Canvas、ゲーム的演出
Web Animations APIJavaScriptから標準アニメーションを制御一時演出、再生制御
ライブラリ複雑な動きを簡単に扱う高度なタイムライン、物理演算
フレームワーク連携状態と動きを結びつけるReact、VueのUI制御

実装方法を選ぶときは、動きの複雑さ、保守性、パフォーマンス、チームの慣れを考える必要があります。単純な動きには単純な方法を使うことが、長期的には最も安定します。

9. 保守性と設計の違い

アニメーションは、初期実装だけでなく、長期運用での保守性も重要です。小規模な画面ではその場で動きを書いても問題になりにくいですが、大規模UIでは、アニメーション時間、イージング、表示ルール、状態管理がバラバラになると、UI全体の一貫性が崩れます。動きの設計も、色や余白と同じようにルール化する必要があります。

CSSはデザインルールとして管理しやすく、JavaScriptはロジックと結びつきやすいという違いがあります。どちらを使う場合でも、アニメーションをその場限りの実装にせず、再利用できる形にすることが大切です。特にチーム開発では、誰が見ても分かるルールが必要になります。

9.1 CSSはデザインルール化しやすい

CSSアニメーションは、デザインシステムの一部として管理しやすいです。たとえば、短いフィードバックは120ms、通常の表示切り替えは200ms、画面遷移は300msのようにルール化できます。イージングも、標準の動き、強調の動き、退出の動きなどに分けて管理できます。

このようにCSS側で動きのルールを統一すると、UI全体の一貫性が高まります。ボタンごとにホバー時間が違う、モーダルごとに表示速度が違う、ページごとにイージングが違うと、ユーザーは無意識に違和感を覚えます。CSSアニメーションは、UI全体の動きを整えるための基盤として使いやすいです。

9.2 JavaScriptはロジックと結びつきやすい

JavaScriptアニメーションは、ユーザー入力、アプリ状態、データ、条件分岐と結びつきやすいです。そのため、複雑なインタラクションを作りやすい一方で、ロジックと演出が混ざりやすいという課題があります。たとえば、ドラッグ処理の中に座標計算、状態更新、DOM操作、アニメーション補間がすべて入ると、保守が難しくなります。

JavaScriptでアニメーションを扱う場合は、責務を分けることが重要です。入力取得、状態管理、アニメーション計算、表示反映を分けると、変更に強くなります。また、複雑な処理はカスタムフックやユーティリティ関数に切り出すと、再利用しやすくなります。JavaScriptアニメーションは自由度が高い分、設計の整理が必要です。

9.3 デザイントークンとの連携

デザイントークンとは、色、余白、角丸、フォント、影、アニメーション時間、イージングなどのデザイン値を変数として管理する考え方です。アニメーションもトークン化すると、UI全体の動きを統一しやすくなります。たとえば、--motion-fast--motion-normal--ease-standardのように定義できます。

トークン化することで、デザイナーとエンジニアの認識を合わせやすくなります。動きの時間やイージングがコード内に散らばっていると、変更や統一が難しくなります。デザイントークンとして管理すれば、全体の調整がしやすくなり、大規模UIでも一貫した動きを保ちやすくなります。

使用言語:CSS

ファイル名:motion-tokens.css

:root {  --motion-fast: 120ms;  --motion-normal: 200ms;  --motion-slow: 320ms;  --ease-standard: cubic-bezier(0.2, 0, 0, 1);  --ease-emphasized: cubic-bezier(0.2, 0, 0, 1.2); } .card {  transition:    transform var(--motion-normal) var(--ease-standard),    opacity var(--motion-normal) var(--ease-standard); }

このようにアニメーション値をトークン化すると、個別コンポーネントごとに時間やイージングがバラバラになるのを防ぎやすくなります。

9.4 コンポーネント設計との関係

コンポーネント設計では、アニメーションをコンポーネントの責務としてどこまで持たせるかを考える必要があります。ボタンのホバーや押下フィードバックはボタンコンポーネントに含めてよいですが、画面遷移全体の演出や複数要素をまたぐタイムラインは、個別コンポーネントに閉じ込めると管理しにくくなります。

アニメーションの責務を考えると、部品レベル、レイアウトレベル、ページレベル、アプリ全体レベルで分けると整理しやすくなります。部品レベルではCSS、ページレベルや複雑な演出ではJavaScriptやライブラリを使うなど、階層ごとにルールを決めると、保守性が高まります。

9.5 アニメーションの再利用性

アニメーションを再利用できる形にしておくと、UI全体の一貫性が上がり、実装コストも下がります。たとえば、フェードイン、スライドアップ、押下フィードバック、トースト登場、モーダル表示などは、多くの画面で使い回せます。毎回個別に書くと、速度や動きが少しずつズレていきます。

再利用性を高めるには、共通クラス、CSS変数、コンポーネント、ユーティリティ関数、アニメーションプリセットを用意します。JavaScriptライブラリを使う場合も、直接あちこちに書くのではなく、共通の関数やコンポーネントとして包むと管理しやすくなります。アニメーションは、再利用される前提で設計することが重要です。

9.6 チーム開発での管理方法

チーム開発では、アニメーションのルールがないと、開発者ごとに動きがバラバラになります。ある人は150ms、別の人は400msを使い、ある画面ではスライド、別の画面ではフェードになると、UI全体の統一感が崩れます。アニメーションもデザインシステムの一部として管理する必要があります。

管理方法としては、モーションガイドライン、デザイントークン、共通コンポーネント、レビュー基準を用意すると効果的です。特に、どの場面でCSSを使い、どの場面でJavaScriptを使い、どの場面でライブラリを使うかの基準を決めると、実装の迷いが減ります。チームで共通の判断基準を持つことが重要です。

項目CSSアニメーションJavaScriptアニメーション
管理しやすい領域デザインルール、共通UI入力処理、状態連動、複雑な制御
再利用方法CSSクラス、変数、トークン関数、フック、コンポーネント
リスクルールなしだと動きが散らばるロジックと演出が混ざる
チーム運用ガイドライン化しやすい設計ルールが必要
向いている管理単位部品・状態変化体験フロー・タイムライン

保守性を高めるには、CSSとJavaScriptを対立させるのではなく、役割を分けることが大切です。見た目の共通ルールはCSS、複雑な制御はJavaScriptという分担が基本になります。

10. レスポンシブとアクセシビリティ

アニメーションは、すべてのユーザーに同じように見せればよいわけではありません。画面サイズ、端末性能、操作方法、視覚的な感受性、年齢、利用状況によって、適切な動きは変わります。特にモバイル端末では、画面が小さく、指で操作するため、PCと同じアニメーションが使いやすいとは限りません。

また、アニメーションはアクセシビリティにも関係します。動きが多すぎると、視覚疲労や不快感を生む場合があります。ユーザーによっては、強い動きや揺れが苦手な場合もあります。そのため、prefers-reduced-motionへの対応や、操作不能時間を作らない設計が必要です。

10.1 画面サイズによる動きの調整

画面サイズによって、適切な動きの距離や速度は変わります。デスクトップでは大きなスライドが自然に見えても、モバイルでは画面全体が動きすぎて疲れる場合があります。小さな画面では、動きの距離を短くし、表示切り替えを軽くする方が使いやすいことがあります。

レスポンシブ設計では、レイアウトだけでなくアニメーションも調整する必要があります。モバイルでは、片手操作、スクロール、タップ、スワイプとの相性を考える必要があります。画面が小さいほど、派手な動きよりも、素早く分かりやすい反応が重要になります。

10.2 prefers-reduced-motion への対応

prefers-reduced-motionは、ユーザーがOSやブラウザで「動きを減らす」設定をしている場合に、それをCSSで検知するための仕組みです。強いアニメーションが苦手なユーザーや、視覚的な負担を減らしたいユーザーに配慮できます。Web UIでは、この設定に対応することが望ましいです。

対応方法としては、動きを完全になくす、時間を短くする、移動や回転をフェードに置き換えるなどがあります。すべてのアニメーションを削除する必要はありませんが、強い動きや繰り返しの動きは抑えるべきです。アクセシビリティを考えると、アニメーションはユーザーが制御できるものであることが重要です。

使用言語:CSS

ファイル名:reduced-motion.css

.modal {  transition:    opacity 200ms ease,    transform 200ms ease; } @media (prefers-reduced-motion: reduce) {  .modal {    transition: opacity 80ms ease;    transform: none;  }  * {    animation-duration: 1ms;    animation-iteration-count: 1;    scroll-behavior: auto;  } }

この例では、動きを減らす設定のユーザーに対して、移動や長いアニメーションを抑えています。UXでは、動きを見せることだけでなく、動きを減らす選択肢も重要です。

10.3 視覚疲労を避ける

アニメーションが多い画面は、ユーザーの視覚疲労を増やします。特に、常に動いている要素、点滅、揺れ、回転、視線を奪う装飾が多いと、集中しにくくなります。学習アプリ、業務システム、文章入力画面などでは、過剰な動きは生産性を下げる原因になります。

視覚疲労を避けるには、常時動くアニメーションを減らし、必要なタイミングだけ動かすことが重要です。注意誘導や状態変化には動きを使ってもよいですが、意味のないループ演出は避けるべきです。アニメーションは、ユーザーの集中を助けるために使うべきであり、奪うために使うべきではありません。

10.4 操作不能時間を作らない

アニメーション中にユーザーが操作できない時間が長いと、UXは悪化します。たとえば、画面遷移の演出が終わるまでボタンを押せない、モーダルが開き切るまで入力できない、長い完了演出を見ないと次へ進めないといった状態です。ユーザーは演出よりも目的達成を優先します。

操作不能時間を減らすには、アニメーションを短くし、重要な操作はすぐに可能にする設計が必要です。演出を見せたい場合でも、スキップや即時操作ができるようにするとストレスが減ります。アニメーションは体験を自然にするためのものであり、ユーザーの操作を待たせるためのものではありません。

10.5 モバイル端末での注意点

モバイル端末では、アニメーションの負荷と操作性に注意が必要です。PCよりも性能が低い端末も多く、バッテリーや熱の問題もあります。また、指で操作するため、タップやスワイプの反応が遅れると強い違和感になります。モバイルでは、軽く、短く、入力に対して即時に反応するアニメーションが重要です。

特にスクロール中の重いアニメーションには注意が必要です。スクロールはユーザーの基本操作なので、ここがカクつくと体験全体が悪くなります。モバイルでは、スクロール連動演出を控えめにし、必要な要素だけを動かす設計が安定します。派手な演出より、滑らかな操作感を優先するべきです。

10.6 高齢者・初心者ユーザーへの配慮

高齢者や初心者ユーザーにとって、動きが速すぎたり複雑すぎたりすると、画面の変化を理解しにくくなる場合があります。突然表示が切り替わる、要素が大きく動く、短時間で情報が消えると、操作に不安を感じやすくなります。アニメーションは、ユーザーの理解を助けるものである必要があります。

配慮するには、動きを短くしすぎて見えなくするのではなく、意味が分かる程度に自然な速度にすることが大切です。また、重要な情報はアニメーション後も十分に表示し、ユーザーが自分のペースで確認できるようにします。初心者向けUIでは、派手さよりも分かりやすさと安心感が重要です。

対応項目目的実装・設計の方向
画面サイズ対応端末に合う動きにするモバイルでは距離や時間を短くする
prefers-reduced-motion動きが苦手なユーザーに配慮移動や回転を減らす
視覚疲労対策集中を妨げない常時ループや点滅を避ける
操作不能時間対策操作の待ち時間を減らすアニメーション中でも操作可能にする
モバイル対応入力遅延を防ぐ軽いプロパティを使う
初心者配慮状態変化を理解しやすくする意味のある動きに限定する

アニメーションのアクセシビリティは、特別な対応ではなく、すべてのユーザーにとって使いやすいUIを作るための基本です。動きは必要な範囲で使い、不要な負担を減らすことが重要です。

11. アニメーションライブラリの使い分け

アニメーションライブラリは、CSSや素のJavaScriptだけでは扱いにくい複雑な動きを実装するために使います。Framer Motion、GSAP、Anime.js、Lottie、Three.jsなど、それぞれ得意分野が異なります。ライブラリを使うことで、複雑なタイムライン、物理的な動き、SVGアニメーション、Reactとの連携、リッチな演出を作りやすくなります。

ただし、ライブラリを使えば必ず良いというわけではありません。導入すればバンドルサイズ、学習コスト、保守コストが増える場合があります。単純なフェードやホバーのために大きなライブラリを入れるのは過剰です。ライブラリは、表現したい動きの複雑さとプロジェクトの運用に合っている場合に使うべきです。

11.1 Framer Motion

Framer Motionは、Reactでアニメーションを扱うときに非常に使いやすいライブラリです。コンポーネントの状態とアニメーションを自然に結びつけられるため、ReactアプリのUIアニメーションに向いています。表示・非表示、レイアウト変化、ドラッグ、ページ遷移、状態に応じた動きなどを扱いやすい点が特徴です。

特に、Reactのコンポーネント設計と相性が良く、宣言的にアニメーションを書けます。CSSだけでは管理しにくい状態連動アニメーションでも、Framer Motionを使うとコードが整理されやすくなります。ただし、すべての小さなアニメーションに使うと過剰になる場合があります。React内で複雑なUI遷移が多い場合に検討するとよいです。

11.2 GSAP

GSAPは、複雑なタイムライン制御や高度なアニメーションに強いライブラリです。複数要素を順番に動かす、細かいイージングを制御する、スクロール連動演出を作る、SVGやCanvasと組み合わせるなど、演出力が必要な場面でよく使われます。ランディングページやブランドサイトのように、動きの品質が重要なプロジェクトに向いています。

GSAPは表現力が高い一方で、シンプルなUIには過剰になる場合があります。管理画面や業務アプリで、ボタンやモーダルの軽い動きだけが必要ならCSSで十分です。GSAPは、複雑なタイムラインや高品質な演出が必要な場面で力を発揮します。

11.3 Anime.js

Anime.jsは、比較的軽量で、DOM、SVG、CSSプロパティなどを扱えるアニメーションライブラリです。複数要素のアニメーションやタイムライン制御をシンプルに書きたい場合に向いています。CSSだけでは少し複雑だが、GSAPほど大規模な機能は必要ない場合に選択肢になります。

Anime.jsは、シンプルな演出をJavaScriptでまとめたい場合に便利です。ただし、プロジェクトでReactやVueを使っている場合、状態管理との相性を考える必要があります。ライブラリ選定では、表現力だけでなく、既存の技術構成との相性も重要です。

11.4 Lottie

Lottieは、After Effectsなどで作成したアニメーションをWebやアプリ上で再生するための仕組みです。複雑なイラストアニメーション、キャラクター演出、ブランド演出、空状態のイラスト、完了演出などに向いています。デザイナーが作った動きを比較的忠実に再現しやすい点が特徴です。

ただし、LottieはUI状態の細かい制御や入力連動には向いていない場合があります。再生、停止、ループなどはできますが、ドラッグやスクロールに細かく追従するUI制御には別の方法が必要になることがあります。Lottieは、UIの構造的な動きよりも、リッチなイラスト演出に向いています。

11.5 Three.jsとの違い

Three.jsは、厳密には通常のUIアニメーションライブラリではなく、3D描画のためのライブラリです。3Dオブジェクト、カメラ、ライト、マテリアル、シーン、WebGL描画を扱えます。3D空間を使った演出、製品ビューア、インタラクティブな3D UI、ゲーム的表現などに向いています。

CSSやFramer Motion、GSAPが主に2D UIの動きを扱うのに対して、Three.jsは3Dレンダリングそのものを扱います。そのため、導入コストやパフォーマンス管理も大きくなります。通常のボタンやモーダルのアニメーションに使うものではなく、3D表現がプロダクトの中心になる場合に使うべきです。

11.6 ライブラリを使うべき場面

ライブラリを使うべき場面は、CSSや標準APIだけでは保守しにくい複雑な動きがある場合です。複数要素の順番制御、スクロール連動の高度な演出、物理的な動き、Reactコンポーネントの状態連動、デザイナー制作のリッチアニメーションなどでは、ライブラリが有効です。

一方で、単純なホバー、フェード、モーダル表示、ローディング程度であれば、CSSで十分な場合が多いです。ライブラリは便利ですが、使うほどコードベースに依存が増えます。導入前に、本当にライブラリが必要な複雑さなのか、チームが運用できるか、パフォーマンスに問題がないかを確認する必要があります。

ライブラリ得意分野向いている場面
Framer MotionReactとの状態連動React UI、ページ遷移、ドラッグ
GSAP高度なタイムライン制御ブランドサイト、複雑な演出
Anime.js軽めのJavaScript演出DOMやSVGの中規模アニメーション
Lottieデザイナー制作のアニメーション再生イラスト演出、完了演出、空状態
Three.js3Dレンダリング3D UI、ゲーム的表現、製品ビューア

ライブラリは、表現力を高める強力な道具です。ただし、使う目的が明確でない場合は、CSSや標準APIで十分なことも多いです。

12. よくある失敗パターン

アニメーションの失敗は、見た目だけでなく、UXやパフォーマンスにも影響します。重い、長い、意味がない、状態とズレる、低速端末でカクつくといった問題は、ユーザー体験を大きく下げます。アニメーションは、入れれば良くなるものではありません。むしろ、設計を誤るとUIの品質を壊します。

よくある失敗を知っておくと、実装前に避けやすくなります。特に、すべてJavaScriptで動かす、レイアウトに影響するプロパティを頻繁に変える、演出が長すぎる、意味のない動きを入れる、状態管理と演出がズレるといった問題は、実務でよく起きます。

12.1 すべてJavaScriptで動かして重くなる

CSSで十分なホバー、フェード、スライドまでJavaScriptで制御すると、コード量が増え、パフォーマンスも悪化しやすくなります。特に、毎フレームJavaScriptでスタイルを更新するような実装は、単純なUIフィードバックには過剰です。JavaScriptは強力ですが、使う必要がない場面では使わない方が安定します。

この問題を避けるには、まずCSSで実装できるかを考えることが重要です。JavaScriptは、状態の切り替えや複雑な入力処理だけを担当し、見た目の変化はCSSに任せる設計が有効です。すべてをJavaScriptに寄せるのではなく、CSSとJavaScriptの役割を分けることが大切です。

12.2 topleft を頻繁に変更する

topleftを使って要素を動かすと、レイアウト再計算が発生しやすくなります。小さな画面や少数要素では問題が目立たない場合もありますが、大量の要素や複雑なレイアウトではカクつきの原因になります。アニメーションで位置を変える場合は、できるだけtransformを使う方が安全です。

transform: translate()を使うと、要素の見た目上の位置を変えつつ、周囲のレイアウトへの影響を抑えやすくなります。ドラッグ、スライド、カード移動、モーダル表示などでは、基本的にtransformを優先するのが実務的です。位置を動かすときは、レイアウトを動かすのか、見た目だけを動かすのかを意識する必要があります。

12.3 アニメーションが長すぎる

アニメーションが長すぎると、UIが遅く感じられます。特に、画面遷移、モーダル表示、メニュー開閉、ボタン操作のように頻繁に使う動きが長いと、ユーザーは待たされているように感じます。演出としては美しくても、操作効率を下げてしまう場合があります。

実務では、短いフィードバックは100msから200ms程度、通常の表示切り替えは200msから300ms程度に収めることが多いです。もちろん内容によって変わりますが、頻繁に使うUIほど短くするのが基本です。アニメーションは、見せるためではなく、理解を助けるために使うべきです。

12.4 意味のない揺れや回転を入れる

意味のない揺れや回転は、ユーザーの注意を奪います。ボタンが常に揺れている、カードが不必要に回転する、画面内の複数要素が同時に動くと、ユーザーはどこを見ればよいか分からなくなります。動きが多いほど楽しいUIになるとは限りません。

アニメーションには意味が必要です。エラーなら軽い揺れで注意を促す、完了ならチェック表示で成功を伝える、メニューならスライドで出現位置を示すなど、目的がある動きは理解を助けます。目的のない動きは、短期的には目立っても、長期的には邪魔になります。

12.5 状態と演出がズレる

状態と演出がズレると、ユーザーは混乱します。たとえば、モーダルを閉じたはずなのにアニメーションが残っている、アニメーション中に状態が変わって表示が崩れる、Reactでコンポーネントがすぐアンマウントされて閉じるアニメーションが再生されない、といった問題です。状態管理とアニメーション終了タイミングを整理しないと起きやすくなります。

この問題を防ぐには、状態と表示状態を分けることが有効です。たとえば、isOpenisAnimatingOutを分ける、アニメーション終了後にDOMから削除する、ライブラリの退出アニメーション機能を使うなどの方法があります。アニメーションは見た目の問題に見えて、状態管理と深く関係しています。

12.6 低速端末でカクつく

開発中のPCでは滑らかでも、低速端末や古いスマートフォンではカクつくことがあります。影、ぼかし、大量DOM、重いJavaScript、スクロール連動、多数の同時アニメーションは端末差が出やすいです。アニメーションの品質は、開発環境だけで判断してはいけません。

低速端末でのカクつきを防ぐには、軽いプロパティを使う、同時に動かす要素を減らす、JavaScriptの処理を軽くする、モバイルでは演出を簡略化するなどの対策が必要です。アニメーションは、最も高性能な環境ではなく、実際のユーザー環境で快適に動くことが重要です。

失敗例問題改善策
すべてJavaScriptで動かすコード量と処理負荷が増える単純な状態変化はCSSに任せる
topleftを多用するレイアウト再計算が増えるtransformを使う
長すぎる演出操作が遅く感じる頻繁なUIは短くする
意味のない動き注意が散る目的のある動きに限定する
状態と演出がズレる表示バグが起きる状態遷移と終了タイミングを整理する
低速端末でカクつくUXが悪化する実機確認と負荷削減を行う

アニメーションの失敗は、実装後に気づくと修正コストが高くなります。最初から目的、負荷、状態管理、アクセシビリティを考えて設計することが重要です。

13. 実務での使い分け基準

実務では、CSSとJavaScriptを感覚で選ぶのではなく、判断基準を持つことが重要です。単純な状態変化ならCSS、ユーザー入力にリアルタイムで連動するならJavaScript、複雑なタイムラインならライブラリ、デザイン統一ならCSSトークンというように、役割を分けると設計が安定します。

使い分けの基本は、「その動きは見た目の状態変化なのか、アプリの状態や入力をもとにした制御なのか」です。見た目の状態変化ならCSSに寄せるべきです。入力、データ、条件分岐、時間制御が深く関わるならJavaScriptを使います。判断基準をチームで共有しておくと、実装のばらつきを減らせます。

13.1 単純な状態変化はCSS

単純な状態変化とは、ホバー、フォーカス、アクティブ、開閉、表示、非表示など、開始状態と終了状態が分かりやすい変化です。こうした動きはCSSのtransitionanimationで十分に実装できます。JavaScriptで毎フレーム制御する必要はありません。

CSSで実装すると、コードが短くなり、デザインルールとして管理しやすくなります。ボタンやカードのような共通コンポーネントでは、CSS側にアニメーションルールを持たせることで、UI全体の一貫性も高まります。単純な状態変化には、まずCSSを使うのが基本です。

13.2 入力連動はJavaScript

入力連動のアニメーションでは、ユーザーの操作にリアルタイムで反応する必要があります。ドラッグ、スワイプ、スクロール、ポインター追従、ジェスチャー操作などは、入力値を取得しながら動きを更新します。このような場面では、JavaScriptによる制御が必要です。

ただし、JavaScriptで入力を扱う場合でも、見た目の反映にはtransformやCSS変数を使うと安定しやすくなります。JavaScriptですべてのスタイルを直接制御するのではなく、入力値の計算と状態管理を担当し、表現はCSSと分担する設計が実務的です。

13.3 複雑な順番制御はJavaScript

複数要素を順番に動かす、途中で停止する、ユーザー操作で分岐する、前のアニメーション終了後に次を始めるといった複雑な順番制御はJavaScriptに向いています。CSSのanimation-delayだけでもある程度できますが、条件が増えると管理が難しくなります。

複雑なタイムラインでは、GSAPやFramer Motionなどのライブラリを使うことも検討できます。重要なのは、動きの順番や依存関係をコード上で分かりやすく管理することです。演出が複雑になるほど、アニメーションを設計として扱う必要があります。

13.4 デザイン統一はCSS

デザイン統一を目的とするなら、CSS側でアニメーションルールを管理するのが向いています。アニメーション時間、イージング、移動距離、フェードの強さなどをCSS変数やデザイントークンで定義すれば、UI全体の動きに一貫性が出ます。各コンポーネントが別々の値を持つと、体験がバラバラになります。

JavaScriptで複雑な制御をする場合でも、時間やイージングの値はトークンから参照するとよいです。こうすることで、ロジックはJavaScript、デザインルールはCSSという分担ができます。デザイン統一の観点では、動きも色や余白と同じように設計資産として扱うことが重要です。

13.5 パフォーマンス優先時の判断

パフォーマンスを優先する場合は、まず動かすプロパティを確認します。transformopacityで表現できるなら、CSSでもJavaScriptでも軽くしやすいです。widthheighttopleftbox-shadowfilterなどを頻繁に動かす場合は、負荷に注意が必要です。

また、JavaScriptを使う場合は、毎フレーム何をしているかを確認します。DOMの読み書き、状態更新、再レンダリング、大量計算があると重くなります。パフォーマンス優先なら、CSSで済む部分をCSSに任せ、JavaScriptの更新範囲を最小限にするのが基本です。

13.6 チーム運用での判断

チーム運用では、誰が実装しても同じ判断ができる基準が必要です。ある開発者はCSSで実装し、別の開発者はJavaScriptで実装し、さらに別の開発者はライブラリを導入する状態になると、コードベースが複雑になります。アニメーションの使い分けルールを作ることで、保守性が高まります。

たとえば、「ホバーや表示切り替えはCSS」「ドラッグやスクロール連動はJavaScript」「複雑なタイムラインは承認後にライブラリ使用」「アニメーション値はトークン参照」といったルールを決めます。チームで判断基準を共有すると、UIの一貫性と実装の安定性を両立できます。

判断項目CSSを選ぶJavaScriptを選ぶ
動きの種類単純な状態変化入力や状態に細かく連動
実装対象ボタン、カード、モーダルドラッグ、スクロール、ゲーム的演出
条件分岐少ない多い
タイムライン単純複雑
保守性デザインルールとして管理ロジックとして管理
パフォーマンス軽いプロパティで安定処理量に注意
チーム運用共通CSSで統一共通関数やライブラリで管理

使い分けの基本は、CSSとJavaScriptのどちらが優れているかではなく、どちらの責務に近いかです。見た目の状態変化はCSS、複雑な制御はJavaScriptという分担が実務では扱いやすくなります。

14. CSSとJavaScriptを組み合わせる設計

実務では、CSSとJavaScriptを完全に分けるのではなく、組み合わせて使うことが多いです。JavaScriptで状態を切り替え、CSSで見た目のアニメーションを担当する設計は非常に実用的です。たとえば、JavaScriptでis-openクラスを付け、CSSでモーダルをフェード表示するような方法です。

この分担により、JavaScriptはロジックに集中し、CSSは表現に集中できます。複雑なアプリでは、この役割分担が保守性に大きく影響します。すべてをCSSだけ、またはJavaScriptだけで解決しようとするのではなく、状態、見た目、入力、データの責務を整理することが重要です。

14.1 CSSで見た目を担当する

CSSは、色、透明度、移動、スケール、影、表示状態など、見た目の変化を担当するのに向いています。アニメーション時間、イージング、変化後のスタイルをCSSで管理すれば、デザインルールとして統一しやすくなります。JavaScript側で細かいスタイル値を直接書き換え続けるより、CSSに表現を寄せる方が保守しやすいです。

CSSで見た目を担当させる場合、クラス名やデータ属性で状態を表現すると分かりやすくなります。たとえば、.is-open.is-active[data-state="open"]のように状態を示し、その状態に応じた見た目をCSSで定義します。これにより、状態と表現の関係が明確になります。

14.2 JavaScriptで状態を切り替える

JavaScriptは、ユーザー操作やアプリ状態に応じて、クラスや属性を切り替える役割に向いています。クリックされたら開く、送信中ならローディング状態にする、ドラッグ中なら移動状態にする、エラーならエラー状態にするなど、状態の判断はJavaScriptが担当します。

この設計では、JavaScriptが直接アニメーションを細かく制御するのではなく、状態を切り替えるだけにします。見た目の変化はCSS側で定義するため、ロジックとデザインが分離されます。単純なUIでは、この方法が最も保守しやすいです。

14.3 クラス付与による制御

クラス付与による制御は、CSSとJavaScriptを組み合わせる基本的な方法です。JavaScriptで要素にクラスを追加・削除し、そのクラスに応じてCSSアニメーションを発火させます。モーダル、ドロップダウン、トースト、アコーディオンなどでよく使われます。

この方法の利点は、実装が分かりやすいことです。JavaScriptを見れば状態の切り替えが分かり、CSSを見れば見た目の変化が分かります。ただし、クラス名が増えすぎると管理が難しくなるため、状態名のルールを決めることが重要です。

使用言語:HTML / CSS / JavaScript

ファイル名:modal-example.html / modal.css / modal.js

<button id="openButton">モーダルを開く</button> <div id="modal" class="modal">  <div class="modal__panel">    <button id="closeButton">閉じる</button>    <p>モーダルの内容です。</p>  </div> </div> .modal {  opacity: 0;  pointer-events: none;  transition: opacity 200ms ease; } .modal__panel {  transform: translateY(12px);  transition: transform 200ms ease; } .modal.is-open {  opacity: 1;  pointer-events: auto; } .modal.is-open .modal__panel {  transform: translateY(0); } const modal = document.querySelector("#modal"); const openButton = document.querySelector("#openButton"); const closeButton = document.querySelector("#closeButton"); openButton.addEventListener("click", () => {  modal.classList.add("is-open"); }); closeButton.addEventListener("click", () => {  modal.classList.remove("is-open"); });

この例では、JavaScriptはクラスの切り替えだけを担当し、アニメーションの見た目はCSSが担当しています。シンプルで保守しやすい分担です。

14.4 CSS変数で動きを調整する

CSS変数を使うと、JavaScriptから数値を渡しつつ、見た目の表現はCSSに任せられます。たとえば、スクロール進捗、ドラッグ距離、マウス位置、データ値などをCSS変数に入れ、CSS側でtransformopacityに反映できます。この方法は、JavaScriptとCSSの役割分担を保ちながら、動的な表現を作れる点が便利です。

CSS変数を使う設計では、JavaScriptは値を計算し、CSSはその値を使って見た目を作ります。すべてのスタイルをJavaScriptで直接書くより、デザイン側の調整がしやすくなります。特に、データ連動の進捗バーやスクロール連動の軽い演出に向いています。

使用言語:CSS / JavaScript

ファイル名:progress.css / progress.js

.progress {  --progress: 0;  transform: scaleX(var(--progress));  transform-origin: left center;  transition: transform 160ms ease; } const progress = document.querySelector(".progress"); function updateProgress(value) {  const safeValue = Math.max(0, Math.min(1, value));  progress.style.setProperty("--progress", safeValue); } updateProgress(0.72);

この例では、JavaScriptで進捗値を計算し、CSS変数に渡しています。表示の制御はCSSが担当するため、見た目の調整がしやすくなります。

14.5 React・Vueでの実装パターン

ReactやVueでは、状態に応じてクラスや属性を切り替える実装がよく使われます。たとえば、isOpentrueならis-openクラスを付ける、statussuccessなら成功アニメーションを出す、といった方法です。状態管理はフレームワーク側、見た目の動きはCSSやライブラリ側に任せると整理しやすくなります。

ただし、ReactやVueでは、要素がDOMから削除されるタイミングに注意が必要です。閉じるアニメーションを再生する前に要素が消えると、退出演出が見えません。その場合は、アニメーション終了後に削除する、またはFramer MotionやTransitionコンポーネントのような仕組みを使うと安定します。状態とアニメーションのライフサイクルを合わせることが重要です。

14.6 大規模UIでの分離設計

大規模UIでは、CSSとJavaScriptの役割分担を明確にしないと、アニメーション管理が破綻しやすくなります。画面ごとに個別のアニメーションが増え、JavaScriptで直接スタイルを操作し、CSSにも似た動きが重複すると、どこを直せばよいか分からなくなります。大規模UIでは、動きも設計システムの一部として管理する必要があります。

分離設計では、CSSは共通モーション、状態別スタイル、デザイントークンを担当し、JavaScriptは状態管理、入力処理、条件分岐、データ計算を担当します。複雑なタイムラインやページ演出は、必要に応じてライブラリにまとめます。役割を分けることで、UIの動きが増えても保守しやすくなります。

役割CSSJavaScript
見た目色、透明度、移動、スケール直接持ちすぎない
状態管理クラスや属性に応じた表現状態の判定・切り替え
入力処理基本的には担当しないクリック、ドラッグ、スクロール
データ連動CSS変数で表現値の計算と反映
共通ルールトークン、イージング、時間共通関数、フック
複雑な演出単純な表現部分タイムラインや条件分岐

CSSとJavaScriptを組み合わせる設計では、どちらが主役かではなく、どちらが何を担当するかが重要です。役割分担が明確なほど、アニメーションは保守しやすくなります。

まとめ

CSSアニメーションとJavaScriptアニメーションは、どちらもWeb UIに動きを加えるための重要な手段ですが、得意分野は異なります。CSSは、ホバー、フェード、スライド、ボタンの反応、モーダル表示、ローディングなど、状態変化に合わせた軽量なアニメーションに向いています。宣言的に書けるため、デザインルールとして管理しやすく、共通UIの動きを統一しやすい点が強みです。

一方、JavaScriptアニメーションは、スクロール連動、ドラッグ、スワイプ、ゲーム的なリアルタイム演出、複雑なタイムライン、条件分岐、データ連動など、状態や入力に強く依存する動きに向いています。自由度が高い分、処理負荷や保守性に注意が必要です。requestAnimationFrame、Web Animations API、ライブラリなどを適切に使えば、高度なインタラクションも実装できます。

実務で重要なのは、CSSとJavaScriptを対立させて考えないことです。単純な状態変化はCSS、入力や状態に応じた複雑な制御はJavaScript、デザイン統一はCSSトークン、複雑な演出は必要に応じてライブラリというように、役割を分けることが大切です。アニメーションは、単なる装飾ではなく、状態変化を伝え、操作結果を返し、ユーザーの理解を助けるUX設計の一部です。

良いアニメーションは、ユーザーに気づかれすぎないほど自然でありながら、操作の分かりやすさを確実に高めます。逆に、長すぎる演出、意味のない動き、重い処理、アクセシビリティを無視したアニメーションは、UXを壊します。CSSとJavaScriptの違いを理解し、目的に応じて使い分けることで、滑らかで保守しやすく、ユーザーにとって自然なWeb UIを設計できます。

LINE Chat