キーフレームアニメーションとは

@keyframes で複数の状態を順番に定義し、animation プロパティで自動的に繰り返し再生させる CSS の技法。

概要

@keyframes で「0% の状態」「50% の状態」「100% の状態」のように途中経過を細かく定義し、animation プロパティで要素に適用すると、 ホバーなどの操作がなくても自動で動き続けるアニメーションを作れます。 拍動する通知バッジ、回転し続けるアイコン、上下にバウンドするボタンなど、注意を引きたい部品でよく使われます。

別名

表記ゆれ:キーフレームアニメーション、css animation、@keyframes

「CSS アニメーション」という呼び方が最も広く使われ、@keyframes はその中で使う記法の名前です。

AI への伝え方

「ずっと回転させ続けて」「拍動するアニメーションを付けて」で伝わります。1 回だけ再生するのか、ループさせ続けるのかを animation-iteration-count の指定として伝えると仕様がぶれません。 自動で動き続けるアニメーションは、動きに敏感なユーザーのために prefers-reduced-motion: reduce で止める配慮も必要です。

似たパーツとの違い

「トランジション」はホバーやクリックなど状態が変わったときだけ動く技法で、開始と終了の 2 点しか指定できません。キーフレームアニメーションは途中経過を複数指定でき、操作なしで自動的にループさせられる点が違います。

デモ

拍動

回転

上下バウンド

コード

HTML
<div class="keyframe-animation-demo">
  <div class="keyframe-animation-demo__item">
    <span class="keyframe-animation-demo__dot"></span>
    <p>拍動</p>
  </div>
  <div class="keyframe-animation-demo__item">
    <span class="keyframe-animation-demo__square"></span>
    <p>回転</p>
  </div>
  <div class="keyframe-animation-demo__item">
    <span class="keyframe-animation-demo__ball"></span>
    <p>上下バウンド</p>
  </div>
</div>
CSS
.keyframe-animation-demo {
  display: flex;
  gap: 32px;
  font-family: sans-serif;
  text-align: center;
  color: #333333;
}

.keyframe-animation-demo__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.keyframe-animation-demo__item p {
  margin: 0;
  font-size: 13px;
}

.keyframe-animation-demo__dot {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #0017c1;
  animation: keyframe-animation-demo-pulse 1.4s ease-in-out infinite;
}

@keyframes keyframe-animation-demo-pulse {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.3);
    opacity: 0.6;
  }
}

.keyframe-animation-demo__square {
  width: 36px;
  height: 36px;
  background: #0017c1;
  animation: keyframe-animation-demo-spin 2s linear infinite;
}

@keyframes keyframe-animation-demo-spin {
  to {
    transform: rotate(360deg);
  }
}

.keyframe-animation-demo__ball {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #0017c1;
  animation: keyframe-animation-demo-bounce 1s ease-in-out infinite;
}

@keyframes keyframe-animation-demo-bounce {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-16px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .keyframe-animation-demo__dot,
  .keyframe-animation-demo__square,
  .keyframe-animation-demo__ball {
    animation: none;
  }
}