9.

CSS animationの使い方|@keyframesと短縮記法・timing-function

編集
この記事の要点
  • animation@keyframes で定義した時系列の変化を要素に適用する CSS プロパティ
  • 個別指定: animation-name / -duration / -timing-function / -delay / -iteration-count / -direction / -fill-mode / -play-state
  • 短縮記法: animation: name 1s ease-out 0s infinite alternate forwards;
  • transition は「状態変化のときだけ」、animation は「自分から能動的に」動く
  • prefers-reduced-motion メディアクエリで動きを抑える設定のユーザーに配慮する

animation プロパティとは

animation は CSS だけで時間軸に沿った変化を表現するプロパティです。あらかじめ @keyframes でフレーム(時間点ごとの状態)を定義し、それを animation-name で要素に当てます。transition がイベント駆動(hover などをきっかけに 1 回変化)であるのに対し、animation能動的に何度でも動かせます。

基本構文

/* 1. @keyframes でフレームを定義 */
@keyframes slidein {
  from { transform: translateX(-100%); opacity: 0; }
  to   { transform: translateX(0);     opacity: 1; }
}

/* 2. 要素に適用 */
.item {
  animation-name: slidein;
  animation-duration: 0.5s;
  animation-timing-function: ease-out;
}

/* 短縮記法(1 行) */
.item2 {
  animation: slidein 0.5s ease-out;
}

個別プロパティ一覧

プロパティ意味主な値
animation-name適用する @keyframes 名slidein / none
animation-duration1 回の長さ0.5s / 2s
animation-timing-functionイージングlinear / ease / ease-in-out / cubic-bezier() / steps()
animation-delay開始までの待ち時間0s / 1s
animation-iteration-count繰り返し回数1 / infinite / 3.5
animation-direction進行方向normal / reverse / alternate / alternate-reverse
animation-fill-mode開始前 / 終了後の状態none / forwards / backwards / both
animation-play-state再生 / 一時停止running / paused

短縮記法

/* name | duration | timing-function | delay | iteration | direction | fill-mode | play-state */
.bounce {
  animation: bounce 1s ease-in-out 0s infinite alternate;
}

/* 複数指定(カンマ区切り) */
.complex {
  animation:
    fadein  0.5s ease-out,
    slidein 0.5s ease-out 0.2s;
}

@keyframes の書き方

キーフレームは from/to または % 指定で書きます。% は 0% — 100% の範囲で、自由に中間点を挟めます。

/* 2 点指定 */
@keyframes fadein {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* 多段階指定 */
@keyframes pulse {
  0%   { transform: scale(1);   }
  50%  { transform: scale(1.2); }
  100% { transform: scale(1);   }
}

/* 複数プロパティを同時に */
@keyframes spinFade {
  0%   { transform: rotate(0deg);   opacity: 0; }
  50%  { transform: rotate(180deg); opacity: 1; }
  100% { transform: rotate(360deg); opacity: 0; }
}

animation-fill-mode の挙動

動作開始前動作終了後
none元のスタイル元のスタイルに戻る
forwards元のスタイル最終フレームを保持
backwards最初のフレームを保持(delay 中も)元のスタイル
both最初のフレーム最終フレーム(両方保持)

animation と transition の違い

項目transitionanimation
きっかけ状態変化(hover, クラス付与)要素配置と同時に自動
中間状態2 点(開始 / 終了)のみ多数のキーフレーム可
繰り返し不可infinite
方向の交互不可alternate で可能
典型用途ボタン hoverローディング / 装飾

実例 1: ローディングスピナ

.spinner {
  width: 40px; height: 40px;
  border: 4px solid #eee;
  border-top-color: #3498db;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

実例 2: フェードイン(forwards で残す)

.fade-in {
  opacity: 0;
  animation: fadeIn 0.5s ease-out 0.2s forwards;
}

@keyframes fadeIn {
  to { opacity: 1; }
}

実例 3: hover で一時停止

.marquee {
  animation: scroll 10s linear infinite;
}
.marquee:hover {
  animation-play-state: paused;
}

@keyframes scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}

イージング(timing-function)

性格
linear等速
ease緩急(既定)
ease-inゆっくり始まる
ease-outゆっくり終わる
ease-in-out両端ゆっくり
cubic-bezier(.17,.67,.83,.67)自由曲線
steps(4, end)4 段階の階段(スプライトに向く)

アクセシビリティ — prefers-reduced-motion

OS の「視差効果を減らす」「アニメーションを減らす」設定を有効にしているユーザーには、アニメーションを抑制 / 無効化するのが望ましいです。三半規管が弱い人や、認知特性上不快に感じる人への配慮です。

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

パフォーマンスのコツ

  • 変形は top / left ではなく transform を使う(GPU 合成)
  • 不透明度は opacity を使う(同じく合成レイヤ)
  • animation 用のレイヤを事前生成するなら will-change: transform, opacity
  • 大量要素を同時に animate するとレイヤが増えすぎてメモリ圧迫
  • SVG / canvas / Web Animations API も選択肢に

JavaScript からの制御

const el = document.querySelector('.box');

// 一時停止 / 再生
el.style.animationPlayState = 'paused';
el.style.animationPlayState = 'running';

// 終了イベント
el.addEventListener('animationend',   e => console.log('end',   e.animationName));
el.addEventListener('animationstart', e => console.log('start', e.animationName));
el.addEventListener('animationiteration', e => console.log('loop'));

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. animation-nameプロパティ
  2. animation-duration プロパティ
  3. animation-timing-functionプロパティ
  4. animation-delayプロパティ
  5. animation-iteration-countプロパティ
  6. animation-directionプロパティ
  7. animation-play-stateプロパティ
  8. animation-fill-modeプロパティ
  9. animationプロパティ

最近更新/作成されたページ