mcpField
A
animation-best-practices

animation-best-practices

github.com/millioncoデザイン・UI15.1k200 回インストール2 週間前に更新
リポジトリ

animation-best-practices について

インターフェースのアニメーション実装者向けの実用的なリファレンススキルです。具体的な CSS 例を交え、時間やイージング、操作フィードバック、ホバー、アクセシビリティ、デバッグを解説します。

主な機能

  1. 01アニメーションの記録と確認
  2. 02時間とイージング曲線の選択
  3. 03ボタンとポップオーバーの遷移設計
  4. 04移動要素によるホバーちらつきの防止
  5. 05タッチ操作とターゲットサイズへの配慮

活用シーン

  1. 01新しいインターフェースの動きのレビュー
  2. 02ボタンやポップオーバーの反応改善
  3. 03アニメーションの揺れやちらつきの調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/millionco/react-doctor --skill animation-best-practices

インストール後、Claude Code で/animation-best-practicesを入力して読み込まれたか確認します。

詳細

実用的なアニメーションのヒント

よくあるアニメーションのシナリオを詳しくまとめたリファレンスガイドです。アニメーションを実装するときのチェックリストとしてお使いください。

記録とデバッグ

アニメーションを記録する

何かがおかしいと感じても原因が分からない場合は、アニメーションを記録して、フレームごとに再生してみましょう。通常の速度では見えない細部を確認できます。

ぶれるアニメーションを修正する

CSS トランスフォームアニメーションの開始時や終了時に、GPU と CPU の描画処理の切り替えが原因で、要素が 1px ずれることがあります。

修正方法:

.element {
  will-change: transform;
}

これにより、アニメーション中は要素が GPU 上に維持されるようブラウザーに指示できます。

休憩を取る

一度にアニメーションのコーディングとリリースを済ませようとしないでください。いったん離れて、頭をすっきりさせてから戻りましょう。優れたアニメーションは、数時間ではなく数日かけて確認し、磨き上げるものです。

ボタンとクリックのフィードバック

押したときにボタンを拡大・縮小する

控えめな拡大・縮小のフィードバックを加えると、インターフェースの応答性が高まります。

button:active {
  transform: scale(0.97);
}

インターフェースが操作を受け付けていることを、すぐに視覚的に伝えられます。

scale(0) からアニメーションを開始しない

scale(0) から始めると、要素が突然現れたように見え、不自然な印象になります。

よくない例:

.element {
  transform: scale(0);
}
.element.visible {
  transform: scale(1);
}

よい例:

.element {
  transform: scale(0.95);
  opacity: 0;
}
.element.visible {
  transform: scale(1);
  opacity: 1;
}

しぼんだ風船のように、要素には常に見える形を少し残しておきましょう。

ツールチップとポップオーバー

2回目以降のツールチップではアニメーションを省く

最初のツールチップ:遅延あり+アニメーションあり。2回目以降のツールチップ(別のツールチップが開いている間):遅延なし、即時表示。

.tooltip {
  transition:
    transform 125ms ease-out,
    opacity 125ms ease-out;
  transform-origin: var(--transform-origin);
}

.tooltip[data-starting-style],
.tooltip[data-ending-style] {
  opacity: 0;
  transform: scale(0.97);
}

/* Skip animation for subsequent tooltips */
.tooltip[data-instant] {
  transition-duration: 0ms;
}

Radix UI と Base UI は、data-instant 属性でこのパターンをサポートしています。

アニメーションの起点を表示位置に合わせる

ポップオーバーは中央からではなく、トリガーから拡大するようにしましょう。

/* Default (wrong for most cases) */
.popover {
  transform-origin: center;
}

/* Correct - scale from trigger */
.popover {
  transform-origin: var(--transform-origin);
}

Radix UI:

.popover {
  transform-origin: var(--radix-dropdown-menu-content-transform-origin);
}

Base UI:

.popover {
  transform-origin: var(--transform-origin);
}

速度とタイミング

アニメーションをすばやくする

同じ読み込み時間でも、スピナーの回転を速くするとアプリが速く感じられます。180ms の選択アニメーションは、400ms のものより応答性が高く感じられます。

ルール: UI アニメーションは 300ms 未満にしましょう。

キーボード操作にアニメーションを使わない

矢印キーでのナビゲーションやキーボードショートカットは、毎日何百回も繰り返し使われます。アニメーションがあると、動作が遅く、操作と切り離されているように感じられます。

アニメーションを使わない操作:

  • 矢印キーによるリストのナビゲーション
  • キーボードショートカットへの応答
  • タブやフォーカスの移動
頻繁に使う要素には注意する

ホバーエフェクトは便利ですが、1日に何度も使う場合は、アニメーションをまったく使わないほうがよいこともあります。

ガイドライン: 自分のプロダクトを毎日使ってみましょう。繰り返し使ううちに、どのアニメーションが煩わしくなるか分かります。

ホバー状態

ホバー時のちらつきを修正する

ホバーアニメーションによって要素の位置が変わると、カーソルが要素から外れ、ちらつきが発生することがあります。

問題:

.box:hover {
  transform: translateY(-20%);
}

解決方法: 子要素をアニメーションさせます。

<div class="box">
  <div class="box-inner"></div>
</div>
.box:hover .box-inner {
  transform: translateY(-20%);
}

.box-inner {
  transition: transform 200ms ease;
}

親要素のホバー範囲を安定させたまま、子要素を動かせます。

タッチデバイスではホバーを無効にする

タッチデバイスには本当のホバー操作がありません。指が意図せず動くと、不要なホバー状態が発生します。

@media (hover: hover) and (pointer: fine) {
  .card:hover {
    transform: scale(1.05);
  }
}

注: Tailwind v4 の hover: クラスは、デバイスがホバーに対応している場合にのみ自動的に適用されます。

タッチ操作とアクセシビリティ

適切なターゲット領域を確保する

小さなボタンはタップしにくいものです。疑似要素を使うと、レイアウトを変えずにヒット領域を広げられます。

最小ターゲットサイズ: 44px(Apple および WCAG の推奨値)

@utility touch-hitbox {
  position: relative;
}

@utility touch-hitbox::before {
  content: "";
  position: absolute;
  display: block;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 100%;
  min-height: 44px;
  min-width: 44px;
  z-index: 9999;
}

使用例:

<button className="touch-hitbox">
  <BellIcon />
</button>

イージングの選択

表示・非表示には ease-out を使う

要素を表示または非表示にするときは、ease-out を使いましょう。最初の動きが速いため、応答性が高く感じられます。

.dropdown {
  transition:
    transform 200ms ease-out,
    opacity 200ms ease-out;
}

ease-in は動き出しが遅いため、UI には適しません。同じ時間をかけても、動きが後半に偏るため、より遅く感じられます。

画面上での移動には ease-in-out を使う

すでに表示されている要素を移動させるときは、ease-in-out を使いましょう。車のような自然な加速と減速を再現できます。

.slider-handle {
  transition: transform 250ms ease-in-out;
}
カスタムイージングカーブを使う

組み込みの CSS カーブは、通常、効果が弱すぎます。カスタムカーブを使うと、意図のある動きを作れます。

参考資料:

視覚的なテクニック

代替手段としてぼかしを使う

イージングやタイミングの調整で問題を解決できない場合は、微妙なぼかしを加えて不完全さを隠します。

.button-transition {
  transition:
    transform 150ms ease-out,
    filter 150ms ease-out;
}

.button-transition:active {
  transform: scale(0.97);
  filter: blur(2px);
}

ぼかしを使うと、状態間の視覚的な隙間が埋まり、目にはより滑らかな遷移として映ります。2つの状態は別々のオブジェクトのように見えず、互いになじみます。

パフォーマンスに関する注意: 特にSafariでは、ぼかしを20px未満に抑えてください。

細部が重要な理由

「見えない細部がすべて合わさることで、かすかに聞こえる何千もの声が調和して歌うように、ただ見事なものが生まれます。」 — Paul Graham、Hackers and Painters

気づかれない細部は良いものです。ユーザーはストレスなくタスクを完了できます。優れたインターフェースは、アニメーションを鑑賞させるのではなく、ユーザーが目標を容易に達成できるようにします。

コメント