メインコンテンツまでスキップ

アニメーション

この章では、Tailwind CSS でアニメーションを実装する方法を学びます。

トランジション

基本

<!-- トランジションを有効化 -->
<button class="transition bg-blue-500 hover:bg-blue-600">
自動でトランジション
</button>

トランジションプロパティ

クラス対象プロパティ
transition-noneなし
transition-allすべて
transition一般的なプロパティ
transition-colors色関連
transition-opacity透明度
transition-shadowシャドウ
transition-transform変形
<button class="transition-colors bg-blue-500 hover:bg-blue-600">
色のみトランジション
</button>

<div class="transition-transform hover:scale-105">
変形のみトランジション
</div>

持続時間

<div class="transition duration-75">75ms</div>
<div class="transition duration-100">100ms</div>
<div class="transition duration-150">150ms (デフォルト)</div>
<div class="transition duration-200">200ms</div>
<div class="transition duration-300">300ms</div>
<div class="transition duration-500">500ms</div>
<div class="transition duration-700">700ms</div>
<div class="transition duration-1000">1000ms</div>

イージング

<div class="transition ease-linear">線形</div>
<div class="transition ease-in">開始時に遅く</div>
<div class="transition ease-out">終了時に遅く</div>
<div class="transition ease-in-out">両端で遅く</div>

遅延

<div class="transition delay-75">75ms 遅延</div>
<div class="transition delay-100">100ms 遅延</div>
<div class="transition delay-150">150ms 遅延</div>
<div class="transition delay-200">200ms 遅延</div>
<div class="transition delay-300">300ms 遅延</div>
<div class="transition delay-500">500ms 遅延</div>

Transform

スケール (拡大・縮小)

<div class="scale-0">0%</div>
<div class="scale-50">50%</div>
<div class="scale-75">75%</div>
<div class="scale-90">90%</div>
<div class="scale-100">100% (デフォルト)</div>
<div class="scale-105">105%</div>
<div class="scale-110">110%</div>
<div class="scale-125">125%</div>
<div class="scale-150">150%</div>

<!-- X 軸・Y 軸個別 -->
<div class="scale-x-50">横 50%</div>
<div class="scale-y-150">縦 150%</div>

回転

<div class="rotate-0">0 度</div>
<div class="rotate-45">45 度</div>
<div class="rotate-90">90 度</div>
<div class="rotate-180">180 度</div>
<div class="-rotate-45">-45 度</div>

移動 (Translate)

<div class="translate-x-4">右に 16px</div>
<div class="translate-y-4">下に 16px</div>
<div class="-translate-x-4">左に 16px</div>
<div class="-translate-y-4">上に 16px</div>
<div class="translate-x-1/2">右に 50%</div>
<div class="-translate-x-1/2 -translate-y-1/2">左上に 50% ずつ</div>

傾斜 (Skew)

<div class="skew-x-6">X 軸に 6 度傾斜</div>
<div class="skew-y-6">Y 軸に 6 度傾斜</div>
<div class="-skew-x-6">X 軸に -6 度傾斜</div>

変形の原点

<div class="origin-center">中央 (デフォルト)</div>
<div class="origin-top"></div>
<div class="origin-top-right">右上</div>
<div class="origin-right"></div>
<div class="origin-bottom-right">右下</div>
<div class="origin-bottom"></div>
<div class="origin-bottom-left">左下</div>
<div class="origin-left"></div>
<div class="origin-top-left">左上</div>

3D トランスフォーム (v4)

3D 変形は GPU 利用だがメモリ消費に注意

3D トランスフォームは transform プロパティを使用するため GPU アクセラレーションが効きますが、perspectivetransform-3d を多用するとメモリ消費が増加する場合があります。複雑な 3D シーンでは、必要な要素のみに適用してください。

v4 では 3D 変形がサポートされています。

Perspective

<!-- 名前付きの値 -->
<div class="perspective-normal">標準的な遠近感 (500px)</div>
<div class="perspective-midrange">中距離の遠近感 (800px)</div>

<!-- 任意の値を指定する場合 -->
<div class="perspective-[500px]">500px の遠近感</div>
<div class="perspective-[1000px]">1000px の遠近感</div>
perspective の名前付き値と任意値の使い分け

v4 の perspective ユーティリティは、perspective-dramatic (100px) や perspective-near (300px) などの名前付きの値を使用します。ほかに perspective-normal (500px)、perspective-midrange (800px)、perspective-distant (1200px) があります。任意の px 値はブラケット構文 (perspective-[500px]) で指定してください。

3D 回転

<div class="rotate-x-45">X 軸で 45 度回転</div>
<div class="rotate-y-45">Y 軸で 45 度回転</div>
<div class="rotate-z-45">Z 軸で 45 度回転</div>

3D 移動

<div class="translate-z-10">Z 軸に移動</div>

3D 表示の保持

<div class="transform-3d">3D 空間を保持</div>
<div class="transform-flat">フラットに</div>

背面の表示

<div class="backface-visible">背面を表示</div>
<div class="backface-hidden">背面を非表示</div>

組み込みアニメーション

spin (回転)

<svg class="animate-spin h-5 w-5">...</svg>

ping (波紋)

<span class="relative flex h-3 w-3">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
</span>

pulse (脈動)

<div class="animate-pulse bg-gray-200 h-4 rounded-sm"></div>

bounce (バウンス)

<svg class="animate-bounce h-6 w-6"></svg>

アニメーションの制御

Tailwind v4 のコア組み込みアニメーションは animate-spin / animate-ping / animate-pulse / animate-bounce / animate-none の 5 種です。実行回数・方向・再生状態を変えるユーティリティはコアに用意されていないため、任意プロパティ構文で個別に指定します(複雑なアニメーションは カスタマイズ のように @theme--animate-* を定義します)。

<!-- 実行回数 (animate-spin は infinite なので任意プロパティで上書き) -->
<div class="animate-spin [animation-iteration-count:1]">1 回</div>
<div class="animate-spin [animation-iteration-count:2]">2 回</div>

<!-- 方向 -->
<div class="animate-spin [animation-direction:reverse]">逆方向</div>
<div class="animate-spin [animation-direction:alternate]">交互</div>

<!-- 再生状態 (ホバーで一時停止) -->
<div class="animate-spin hover:[animation-play-state:paused]">ホバーで一時停止</div>

実践例

ホバーアニメーション

<!-- カードホバー -->
<div class="transition-all duration-300 hover:scale-105 hover:shadow-xl">
<div class="bg-white rounded-lg shadow-sm p-6">
カードコンテンツ
</div>
</div>

<!-- ボタンホバー -->
<button class="relative overflow-hidden bg-blue-500 text-white px-6 py-3 rounded-lg group">
<span class="relative z-10">ホバーしてみて</span>
<span class="absolute inset-0 bg-blue-600 transform scale-x-0 group-hover:scale-x-100 transition-transform origin-left"></span>
</button>

<!-- 画像ホバー -->
<div class="overflow-hidden rounded-lg">
<img
src="..."
class="transition-transform duration-500 hover:scale-110"
/>
</div>

フェードイン

<!-- CSS アニメーションで実装 -->
<style>
@keyframes fade-in {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
</style>

<div class="animate-[fade-in_0.5s_ease-out]">
フェードインするコンテンツ
</div>

ローディングスピナー

<div class="flex items-center justify-center">
<div class="animate-spin rounded-full h-12 w-12 border-4 border-blue-500 border-t-transparent"></div>
</div>

<!-- ドットローディング -->
<div class="flex gap-1">
<div class="w-2 h-2 bg-blue-500 rounded-full animate-bounce [animation-delay:-0.3s]"></div>
<div class="w-2 h-2 bg-blue-500 rounded-full animate-bounce [animation-delay:-0.15s]"></div>
<div class="w-2 h-2 bg-blue-500 rounded-full animate-bounce"></div>
</div>

スケルトンローディング

<div class="animate-pulse space-y-4">
<div class="h-4 bg-gray-200 rounded-sm w-3/4"></div>
<div class="h-4 bg-gray-200 rounded-sm"></div>
<div class="h-4 bg-gray-200 rounded-sm w-5/6"></div>
<div class="flex gap-4">
<div class="h-12 w-12 bg-gray-200 rounded-full"></div>
<div class="flex-1 space-y-2 py-1">
<div class="h-4 bg-gray-200 rounded-sm w-1/2"></div>
<div class="h-4 bg-gray-200 rounded-sm w-1/4"></div>
</div>
</div>
</div>

アコーディオン

<details class="group border border-gray-300 rounded-lg">
<summary class="flex justify-between items-center p-4 cursor-pointer">
<span>アコーディオンタイトル</span>
<svg class="w-5 h-5 transition-transform duration-200 group-open:rotate-180">

</svg>
</summary>
<div class="overflow-hidden transition-all duration-300 max-h-0 group-open:max-h-screen">
<div class="p-4 pt-0">
アコーディオンの内容...
</div>
</div>
</details>

モーダルアニメーション

open: バリアントは <details><dialog> のように open 属性を持てる要素にのみ適用されます。<dialog> 要素を使い、open 属性の有無で表示を切り替えます。

<!-- オーバーレイ (dialog 自体がオーバーレイを兼ねる) -->
<dialog class="group fixed inset-0 bg-black/50 transition-opacity duration-300
opacity-0 open:opacity-100">

<!-- モーダル -->
<div class="fixed inset-0 flex items-center justify-center p-4">
<div class="bg-white rounded-xl shadow-xl max-w-lg w-full
transform transition-all duration-300
scale-95 opacity-0 group-open:scale-100 group-open:opacity-100">
モーダルコンテンツ
</div>
</div>
</dialog>

下線アニメーション

<a href="#" class="relative inline-block group">
リンクテキスト
<span class="absolute bottom-0 left-0 w-full h-0.5 bg-blue-500
transform scale-x-0 group-hover:scale-x-100
transition-transform duration-300 origin-left"></span>
</a>

カードフリップ

<div class="perspective-[1000px] w-64 h-40">
<div class="relative w-full h-full transition-transform duration-500
transform-3d hover:rotate-y-180">
<!-- 表面 -->
<div class="absolute inset-0 backface-hidden bg-blue-500 text-white
rounded-lg flex items-center justify-center">
表面
</div>
<!-- 裏面 -->
<div class="absolute inset-0 backface-hidden bg-purple-500 text-white
rounded-lg flex items-center justify-center rotate-y-180">
裏面
</div>
</div>
</div>

アニメーションのベストプラクティス

1. パフォーマンスを意識

<!-- Good: transform / opacity を使用 (GPU アクセラレーション) -->
<div class="transition-transform hover:translate-x-2">...</div>

<!-- Avoid: left / top を使用 (リフロー発生) -->
<div class="transition-all hover:left-2">...</div>

2. アクセシビリティに配慮

prefers-reduced-motion は OS の「視差効果を減らす」設定に対応するメディアクエリです。前庭障害を持つユーザーや、動きの多い UI を好まないユーザーに配慮するために使用します。

<!-- motion-safe: モーション許可時のみアニメーション -->
<div class="motion-safe:animate-bounce motion-reduce:animate-none">
...
</div>

<!-- motion-reduce: モーション軽減時の代替 -->
<div class="transition-transform motion-safe:hover:scale-105 motion-reduce:hover:opacity-80">
スケールの代わりに透明度で変化を示す
</div>
motion-safe を基本にする

アニメーションを多用するページでは、motion-safe: を基本にすることを推奨します。これにより、モーション軽減設定のユーザーにはアニメーションなしの状態がデフォルトで提供されます。

3. 適切な持続時間

<!-- マイクロインタラクション: 100-200ms -->
<button class="transition-colors duration-150">...</button>

<!-- ページ遷移・モーダル: 200-300ms -->
<div class="transition-all duration-300">...</div>

<!-- 強調: 300-500ms -->
<div class="transition-transform duration-500">...</div>

まとめ

  • transition でトランジションを有効化
  • duration-* / ease-* / delay-* でカスタマイズ
  • scale-* / rotate-* / translate-* で変形
  • v4 では 3D トランスフォームをサポート
  • animate-spin / animate-pulse 等の組み込みアニメーション
  • motion-safe: / motion-reduce: でアクセシビリティ対応

次に読む