animation-best-practices について
インターフェースのアニメーション実装者向けの実用的なリファレンススキルです。具体的な CSS 例を交え、時間やイージング、操作フィードバック、ホバー、アクセシビリティ、デバッグを解説します。
主な機能
- 01アニメーションの記録と確認
- 02時間とイージング曲線の選択
- 03ボタンとポップオーバーの遷移設計
- 04移動要素によるホバーちらつきの防止
- 05タッチ操作とターゲットサイズへの配慮
活用シーン
- 01新しいインターフェースの動きのレビュー
- 02ボタンやポップオーバーの反応改善
- 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
気づかれない細部は良いものです。ユーザーはストレスなくタスクを完了できます。優れたインターフェースは、アニメーションを鑑賞させるのではなく、ユーザーが目標を容易に達成できるようにします。