タイトル: @keyframes
SEOタイトル: CSS @keyframes 完全ガイド(書き方 / from-to / animation プロパティ / 実例集)
| この記事の要点 |
|
CSS @keyframes とは
@keyframes は CSS アニメーションを定義するためのアットルールです。名前付きのアニメーション設計図を作り、それを animation プロパティで要素に適用します。
transition が「2 つの状態の間をなめらかにつなぐ」のに対し、@keyframes は複数のキー(時点)を経由する複雑な動きやループ再生を実現できます。
基本構文
@keyframes アニメーション名 {
from { /* 開始 = 0% */
プロパティ: 値;
}
to { /* 終了 = 100% */
プロパティ: 値;
}
}
要素 {
animation-name: アニメーション名;
animation-duration: 時間;
}
例 1: h1 をスライドインさせる
h1 {
animation-duration: 2s;
animation-name: slidein;
}
@keyframes slidein {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 0%;
width: 100%;
}
}
ロード時に h1 が画面右から左へスライドインしてきます。
例 2: パーセント指定で 3 点以上のキー
動きを細かく制御したいときはパーセント (0%〜100%) で時点を刻みます。
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-30px); }
100% { transform: translateY(0); }
}
.ball {
width: 50px; height: 50px;
background: #2980b9; border-radius: 50%;
animation: bounce 1s ease-in-out infinite;
}
animation プロパティ一覧
| プロパティ | 意味 | 例 |
|---|---|---|
animation-name | @keyframes の名前 | slidein |
animation-duration | 1 サイクルの長さ | 2s / 500ms |
animation-timing-function | 速度の進み方 | ease / linear / cubic-bezier() |
animation-delay | 開始までの遅延 | 0.5s |
animation-iteration-count | 繰り返し回数 | 1 / 3 / infinite |
animation-direction | 再生方向 | normal / reverse / alternate |
animation-fill-mode | 開始前 / 終了後のスタイル保持 | none / forwards / backwards / both |
animation-play-state | 再生 / 一時停止 | running / paused |
ショートハンド (animation)
個別指定はうるさいので、ショートハンドでまとめるのが定番。順不同で書ける(数値 2 個目は delay として解釈される点に注意)。
/* 個別指定 */
.box {
animation-name: slidein;
animation-duration: 2s;
animation-timing-function: ease-in-out;
animation-delay: 0.5s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-fill-mode: both;
}
/* ショートハンド */
.box {
animation: slidein 2s ease-in-out 0.5s infinite alternate both;
}
timing-function(イージング)
| 値 | 動き |
|---|---|
| linear | 等速 |
| ease (デフォルト) | ゆっくり → 速く → ゆっくり |
| ease-in | ゆっくり → 速く |
| ease-out | 速く → ゆっくり |
| ease-in-out | 両端ゆっくり、中央速い |
| cubic-bezier(.17,.67,.83,.67) | カスタム曲線 |
| steps(4, end) | 4 段階のステップ(スプライト用) |
GPU 加速されるプロパティを選ぶ
アニメーション対象を transform と opacity に絞ると合成のみで描画でき、レイアウト再計算が走らないため60fps を維持しやすくなります。
| プロパティ | 負荷 |
|---|---|
| transform / opacity | 軽い (Compositor のみ) |
| color / background-color | 中(Paint) |
| width / height / margin / left / top | 重い(Layout + Paint) |
例: スライドインは margin-left ではなく transform: translateX(...) を使うのが推奨。
/* NG: レイアウト再計算が毎フレーム */
@keyframes slidein-bad {
from { margin-left: 100%; }
to { margin-left: 0; }
}
/* OK: GPU 加速 */
@keyframes slidein-good {
from { transform: translateX(100%); }
to { transform: translateX(0); }
}
fill-mode で「終わった状態を保持」
デフォルトでアニメーション終了後は元のスタイルに戻ります。終了後の状態を保持したいときは fill-mode: forwards。
.fade-in {
opacity: 0;
animation: fade 1s ease-out forwards;
}
@keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
/* これがないと終了後 opacity:0 に戻ってまた見えなくなる */
JavaScript からの制御
// 一時停止
element.style.animationPlayState = "paused";
// 再開
element.style.animationPlayState = "running";
// アニメーション完了を検知
element.addEventListener("animationend", () => {
console.log("アニメーション終了!");
});
transition との違い
| 機能 | transition | @keyframes |
|---|---|---|
| キーポイント数 | 2 (開始 / 終了) | 任意(0% 〜 100% で複数) |
| 無限ループ | × | ○ |
| ページ読み込み時に自動再生 | × | ○ |
| 逆再生 / 往復 | × | ○ (direction) |
| JS なしで成立 | onload では× (クラス追加が要る) | ○ (load 時自動) |
| 用途 | hover / focus の微変化 | 複雑な動き、ループ |
FAQ
Q: @keyframes が動かない
A: 名前のタイポ、ベンダープレフィクス不足、animation-duration 未設定(デフォルト 0s で実質再生されない)が定番原因。
Q: 古いブラウザに対応するには
A: -webkit- プレフィクスを付ける。モダンブラウザのみで良いなら不要。Autoprefixer で自動付与可能。
Q: 重ねがけはできる?
A: できる。animation: fade 1s, slide 2s; のようにカンマ区切り。