モーションの品質は、数や滑らかさでは決まりません。操作の結果、要素の関係、次に見る場所を、静止画より短く正確に伝えられるかで決まります。
すべての要素を下からfade-inさせると、最初は整って見えます。しかし、読む順序とアニメーション順序がずれ、戻ってきた本文まで再び待たせるなら、情報設計を弱めています。
先に結論:動きの担当を一つに絞る
モーションは、状態変化、視線誘導、空間関係、フィードバックのどれか一つを担当させます。担当する意味を一文で説明できない動きは入れず、機能そのものはOffやreduced motionでも残します。
モーションを四つの役割へ限定する
| 役割 | 入れる条件 | 確認する代替 |
|---|---|---|
| 状態変化 | 開閉・選択前後の連続性が理解を助ける | 開閉結果、見出し、focus |
| 視線誘導 | エラー・更新結果・次の場所を一度だけ示す | 色以外の文言や境界 |
| 空間関係 | ノードや線の関係を追いやすくする | HTMLの一覧、ラベル、詳細文 |
| フィードバック | 押下・保存・反映を短く伝える | 同じ場所のstatus text |
画面全体の導入演出、常時点滅、カーソル追従、スクロール位置の上書きは、四役割に無理に含めません。情報の優先順位や読み上げ順を変えるなら、モーションではなく構造を見直します。
状態変化
開く、閉じる、選ぶ、保存する。操作前後の状態が連続して見えると、ユーザーは「どこから何が現れたか」を追いやすくなります。
ただし、状態変化はOffでも機能しなければなりません。ダイアログが開く、詳細が表示される、選択結果が更新されるという機能は維持し、移動や透明度の補間だけを止めます。
視線誘導
エラーが出た入力、更新された結果、次に読む見出しへ注意を移す用途です。画面全体を動かすより、境界色や短いopacity変化で十分なことが多くあります。
視線誘導は一度で止めます。常時点滅や呼吸するCTAは、ページ内の優先順位を永続的に奪います。
空間関係
Project Orbitで選択ノードと関連線が強調されるように、要素同士のつながりを示します。ここで重要なのは回転そのものではなく、どの線が現在の関係か分かることです。
関係は色だけに依存させません。線の太さ、ラベル、詳細パネルの文章を組み合わせ、CanvasやSVGを見られない人にも同じ意味を渡します。
フィードバック
ボタンが押された、URLがコピーされた、条件が反映されたことを伝えます。操作への返答は速く、短く、同じ場所に出します。意味のないカウントアップや長い完了演出は不要です。
reduced motionは「全部消す」設定ではない
W3C WCAG 2.2のAnimation from Interactionsは、操作で起きる不要な動きを無効化できることを扱っています。ここで止めるのは機能ではなく、理解に必須でない運動です。
BUILD ORBITでは、次の四段階を用意しています。
| 設定 | 扱い |
|---|---|
| System | OSのprefers-reduced-motionを尊重する |
| Off | パララックス、軌道運動、装飾的な移動を停止 |
| Subtle | 短い状態遷移だけを残す |
| Full | 関係を示すゆっくりした運動まで許可 |
ユーザーが明示的に選んでいない間はSystemを使います。端末設定を勝手に上書きしないためです。
CSSだけで十分な場合、JavaScriptが必要な場合
色、opacity、transform、開閉の短い遷移だけならCSSで十分です。detailsの開閉やfocus ringの変化を、JavaScriptで再実装する必要はありません。選択結果の計算、履歴・共有URLとの同期、Orbitの関係強調のように状態とデータが変わる場合だけJavaScriptを使い、HTMLの説明とfallbackを先に作ります。
BUILD ORBITのMotion Dialで設定の境界を、Performance Observatoryで初期JS・長いタスク・描画の観点を確認できます。公開前の総合判定は品質ゲートとMethodへ戻します。
モバイルでは、同じ動きを縮小しない
ポインター位置へ反応する奥行きは、タッチ端末では成立しません。小さな画面へ同じノード配置を押し込むより、タップ領域を広げるか、一覧型へ変えます。
モバイルで判断する項目は次の通りです。
pointer: coarseなら追従効果を止める。- hoverでしか見えない情報を作らない。
- 44px前後のタップ領域を確保する。
- 画面回転後も固定要素が本文を隠さない。
- 長い日本語ラベルを省略しすぎない。
表現の同一性より、意味と操作結果の同一性を優先します。
モーション採用記録を残す
演出を採用した理由を「雰囲気がよい」で終わらせないため、各動きに担当、停止条件、代替、確認方法を付けます。これは新しいUIを増やすための仕様ではなく、既存の動きを削る判断にも使う記録です。
| 記録欄 | 例 | 不合格にする条件 |
|---|---|---|
| 担当する意味 | Orbitのノード関係を追いやすくする | 意味を一文で説明できない |
| 動く範囲 | 装飾ノードの移動だけ | 本文・見出し・focusまで移動させる |
| 停止条件 | Off、OSのreduced motion、coarse pointer | 設定を変えても常時運動が残る |
| 静的な代替 | Project名、関係リンク、説明文 | SVGがないと関係が分からない |
| 確認方法 | keyboard、320px、Performance Observatory | smoothさだけを主観で保証する |
Motion Dialは設定の差を観測し、Performance Observatoryは取得できたセッション値だけを表示します。どちらも「動いた」「速い」という成果を保証するものではなく、動きを切っても判断材料が残るかを確認する補助です。
パフォーマンスを落とさない実装条件
モーションはtransformとopacityを中心にします。幅、高さ、top、leftを連続更新すると、レイアウト計算が増えます。
ポインターやスクロールを読む場合は、次を守ります。
- listenerを
passiveにできるか確認する。 - 連続更新は
requestAnimationFrameへまとめる。 - コンポーネントのunmountでlistenerとobserverを解除する。
document.hiddenでは装飾更新を止める。- 低性能端末やcoarse pointerでは効果を減らす。
常時60fpsを保証できない表現は、主要導線へ置きません。重いWebGLを使う場合も初期バンドルから分離し、静的SVGやHTMLのfallbackを先に完成させます。
モバイルやpointer: coarseでは、ポインター座標を読む処理を省き、タップ後の短い状態変化や一覧へ落とします。Performance Observatoryで確認できない処理を「滑らか」と断定せず、CSSだけで成立する表現を優先します。
よくあるアンチパターン
- 本文が表示されるまで待たせるページ遷移。
- スクロール位置を勝手に補正する演出。
- 全セクションで同じfade-inを繰り返す。
- カーソルを追い続ける大きな光。
- hoverでカードが大きく傾き、文字が読みにくくなる。
- motion offでコンテンツ自体が非表示になる。
- IntersectionObserverを解除せず、ページ全体を監視し続ける。
迷ったときは静止画へ戻し、「この動きがないと、どの関係が伝わらないか」を答えます。答えがなければ、削る候補です。
リリース前の確認
- キーボードだけで同じ状態へ到達できる。
- Motion Offで機能が残る。
- OSのreduced motionを初期値として尊重する。
- 320pxとlandscapeで横スクロールがない。
- タブを非表示にしたとき、継続描画しない。
- 長時間見ても本文が常に動かない。
- 操作後の結果を色以外でも伝える。
よくある質問
モーション設計FAQ
reduced motionではアニメーションを全部消しますか
機能を消すのではなく、理解に不要な移動・視差・追従・常時運動を止めます。開閉結果、選択結果、focus、状態の文言は残します。
CSSとJavaScriptの境界はどこですか
見た目の遷移と開閉だけならCSSを使います。データ計算、URL履歴、選択関係の変更など状態が変わる場合だけJavaScriptを使い、静的HTMLの説明を先に用意します。
モバイルではデスクトップの動きを縮小すればよいですか
必ずしも縮小しません。coarse pointerで成立しない追従やhover依存を止め、タップ領域、一覧、短い状態変化へ置き換えて意味と操作結果を保ちます。
モーションの性能は何を見ればよいですか
初期JS、長いタスク、layoutを起こす連続更新、画面非表示時の描画を確認します。transformとopacityを中心にし、実測できない60fps保証は書きません。
良いモーションは、ユーザーに「動いた」と意識させることより、「迷わなかった」と感じさせます。動きの量を増やす前に、担当する意味を一つに絞ることが最も効きます。