CSSアニメーションとは
JavaScriptなしで動きのあるUIを実現できます。
2つの方法
- transition: 状態変化をスムーズに(ホバー時など)
- animation: 複雑なアニメーション、自動実行
メリット
- ⚡ パフォーマンスが良い(GPU活用)
- 📝 コードがシンプル
- 🎨 デザイナーでも実装可能
- ♿ アクセシビリティ対応が簡単
1. transition(状態遷移)
プロパティの変化をスムーズにします。
基本的な書き方
.button {
background: #2a2a2a;
color: white;
padding: 1rem 2rem;
border: none;
/* transition: プロパティ 時間 イージング 遅延; */
transition: background 0.3s ease 0s;
}
.button:hover {
background: #ffeb3b;
color: #2a2a2a;
}実装結果
複数プロパティ
/* 個別指定 */
.element {
transition:
background 0.3s ease,
transform 0.2s ease-out,
box-shadow 0.3s ease;
}
/* 一括指定 */
.element {
transition: all 0.3s ease;
}イージング関数
ease デフォルト(ゆっくり→速く→ゆっくり)
linear 一定速度
ease-in ゆっくり開始
ease-out ゆっくり終了
ease-in-out 両端をゆっくり
/* カスタム */
cubic-bezier(0.68, -0.55, 0.265, 1.55) バウンド効果イージング比較
ease:
linear:
ease-in-out:
実用例:カードホバー
<div class="card">
<img src="image.jpg" alt="画像">
<div class="content">
<h3>タイトル</h3>
<p>説明文</p>
</div>
</div>
<style>
.card {
border: 3px solid #2a2a2a;
overflow: hidden;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-10px) scale(1.02);
box-shadow: 10px 10px 0px rgba(0,0,0,0.2);
}
.card img {
width: 100%;
transition: transform 0.5s ease;
}
.card:hover img {
transform: scale(1.1);
}
</style>実装結果
2. animation(キーフレーム)
複雑なアニメーションを定義できます。
基本的な書き方
/* アニメーション定義 */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* または */
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* 適用 */
.element {
animation: fadeIn 1s ease;
/* animation: 名前 時間 イージング; */
}animationの詳細プロパティ
.element {
animation-name: fadeIn; /* アニメーション名 */
animation-duration: 1s; /* 時間 */
animation-timing-function: ease; /* イージング */
animation-delay: 0.5s; /* 遅延 */
animation-iteration-count: infinite; /* 繰り返し */
animation-direction: alternate; /* 方向 */
animation-fill-mode: forwards; /* 終了後の状態 */
animation-play-state: running; /* 再生状態 */
}
/* 一括指定 */
.element {
animation: fadeIn 1s ease 0.5s infinite alternate forwards;
}フェードイン
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 1s ease;
}実装結果
フェードイン
スライドイン
@keyframes slideIn {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.slide-in {
animation: slideIn 0.5s ease;
}実装結果
スライドイン
バウンス
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-30px);
}
}
.bounce {
animation: bounce 0.6s ease infinite;
}実装結果
回転
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.rotate {
animation: rotate 2s linear infinite;
}実装結果
パルス(拡大縮小)
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.2);
opacity: 0.7;
}
}
.pulse {
animation: pulse 1.5s ease infinite;
}実装結果
3. 実用的なアニメーション集
ローディングスピナー
<div class="spinner"></div>
<style>
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
width: 50px;
height: 50px;
border: 5px solid #f5f5f5;
border-top-color: #2196f3;
border-radius: 50%;
animation: spin 1s linear infinite;
}
</style>実装結果
ドットローディング
<div class="dots">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
<style>
@keyframes dotBounce {
0%, 80%, 100% { transform: scale(0); }
40% { transform: scale(1); }
}
.dots {
display: flex;
gap: 10px;
}
.dot {
width: 15px;
height: 15px;
background: #2196f3;
border-radius: 50%;
animation: dotBounce 1.4s infinite ease-in-out;
}
.dot:nth-child(1) { animation-delay: -0.32s; }
.dot:nth-child(2) { animation-delay: -0.16s; }
</style>実装結果
通知バッジ
<div class="notification-badge">3</div>
<style>
@keyframes ping {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(2);
opacity: 0;
}
}
.notification-badge {
position: relative;
background: #f44336;
color: white;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
.notification-badge::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
background: #f44336;
animation: ping 1.5s cubic-bezier(0, 0, 0.2, 1) infinite;
}
</style>実装結果
3
シェイク(振動)
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-10px); }
20%, 40%, 60%, 80% { transform: translateX(10px); }
}
.shake {
animation: shake 0.5s;
}
/* エラー時などに使う */
input.error {
border-color: #f44336;
animation: shake 0.5s;
}グラデーション移動
@keyframes gradientMove {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.gradient-bg {
background: linear-gradient(270deg, #ffeb3b, #4caf50, #2196f3);
background-size: 200% 200%;
animation: gradientMove 5s ease infinite;
}実装結果
グラデーション移動
タイプライター効果
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes blink {
50% { border-color: transparent; }
}
.typewriter {
overflow: hidden;
border-right: 3px solid #2a2a2a;
white-space: nowrap;
animation:
typing 3s steps(30, end),
blink 0.75s step-end infinite;
}4. パフォーマンス最適化
GPUアクセラレーション
/* ✅ 高速(GPUを使う) */
transform: translateX(100px);
transform: scale(1.5);
transform: rotate(45deg);
opacity: 0.5;
/* ❌ 遅い(CPUを使う) */
left: 100px;
width: 200px;
height: 200px;
margin-left: 100px;will-changeの使用
/* アニメーション開始前にヒントを与える */
.element:hover {
will-change: transform, opacity;
}
.element {
transform: translateX(100px);
opacity: 0.5;
}
/* 注意: 常に指定すると逆効果 */複合transformの書き方
/* ✅ 正しい */
transform: translateX(100px) rotate(45deg) scale(1.2);
/* ❌ 間違い(最後のみ適用される) */
transform: translateX(100px);
transform: rotate(45deg);
transform: scale(1.2);5. アクセシビリティ
アニメーション無効化対応
/* ユーザーがアニメーションを無効にしている場合 */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* または個別に */
@media (prefers-reduced-motion: reduce) {
.animated-element {
animation: none;
}
}6. 実践例:モーダル
<div class="modal-overlay">
<div class="modal">
<h2>モーダル</h2>
<p>コンテンツ</p>
<button>閉じる</button>
</div>
</div>
<style>
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from {
transform: translateY(50px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
animation: fadeIn 0.3s ease;
}
.modal {
background: white;
padding: 2rem;
border: 3px solid #2a2a2a;
max-width: 500px;
animation: slideUp 0.4s ease;
}
</style>7. ライブラリ活用
Animate.css
<!-- CDN読み込み -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<!-- 使用 -->
<div class="animate__animated animate__fadeIn">
フェードイン
</div>
<div class="animate__animated animate__bounce">
バウンス
</div>まとめ
CSSアニメーションで快適なUXを実現しましょう。
使い分け
- transition: ホバー、フォーカス、状態変化
- animation: ローディング、通知、複雑な動き
ベストプラクティス
- transform/opacityを優先(パフォーマンス)
- アニメーション時間は0.2s〜0.5s(UX)
- prefers-reduced-motion対応(アクセシビリティ)
- 必要な場所にのみ適用(パフォーマンス)
学習のステップ
- transitionで基礎を学ぶ
- @keyframesで複雑な動きを作る
- パフォーマンスを理解する
- 実際のプロジェクトで活用