Webサイトに動きを加えるとき、CSSアニメーションはとても便利ですよね。ですが「無限ループで繰り返したいけど、動きと動きの間に少し“間隔”を入れたい」「途切れず自然に見えるアニメーションを作りたい」と悩んだ経験はありませんか? animation-iteration-count
や animation-delay
を何となく設定してみても、思ったような効果にならずに手詰まりになってしまう方は少なくありません。特に「CSSだけで実現したい」「JavaScriptに頼りたくない」という制約があると、設定方法や組み合わせ方の理解が欠かせません。
この記事では、CSSアニメーションにおける「繰り返し」と「間隔」の考え方を整理しながら、よく使うプロパティの具体的な使い方から実践的なサンプルコードまで解説していきます。基礎を押さえつつ、実務ですぐに活かせるテクニックを紹介しますので、初心者の方でも実装イメージを掴みやすい内容になっています。
「とりあえずコピペで動かしたい」という方にも、「CSSアニメーションを理屈から理解して使いこなしたい」という方にも役立つ内容になっています。この記事を読み終える頃には、繰り返しと間隔を自在にコントロールできるようになり、より自然で洗練されたアニメーションを実装できるはずです。
ConoHa AI Canvas|ブラウザだけでできる本格的なAI画像生成CSSアニメーションの繰り返しと間隔の基本理解
CSSアニメーションは、@keyframes
で定義した動きをanimation
プロパティで要素に適用することで実現します。しかし、ただ動かすだけでなく、「いつ動き出すか」「何回繰り返すか」「動きの間に間隔を空けるか」といった詳細な制御が、より洗練されたアニメーションには不可欠です。このセクションでは、アニメーションの「時間」と「回数」を制御する基本的なプロパティとその仕組みを解説します。

animation-delayの基礎|初回再生までの「間」を理解する
animation-delay
は、アニメーションが開始されるまでの遅延時間を指定するプロパティです。指定した秒数(s
)またはミリ秒(ms
)が経過してから、アニメーションが再生され始めます。このプロパティは、複数の要素を時間差で動かしたい時や、ページが読み込まれた直後にアニメーションを少し遅らせて再生したい時に非常に役立ちます。
<div class="box delay-example"></div>
.box {
width: 100px;
height: 100px;
background-color: #3498db;
animation-name: slide-in; /* アニメーション名 */
animation-duration: 2s; /* アニメーションの再生時間 */
animation-delay: 1s; /* ★1秒遅れて開始する */
}
@keyframes slide-in {
from {
transform: translateX(-200px);
}
to {
transform: translateX(0);
}
}
animation-delay
は、アニメーションの「再生キュー」に影響を与えます。上記の例では、slide-in
というアニメーションがCSSで定義されていますが、animation-delay: 1s;
という記述があるため、ブラウザはアニメーションの再生を1秒間待機します。この「待機」はアニメーションの進行とは別物であり、アニメーションそのものの再生時間が短くなるわけではありません。あくまで「いつから再生を開始するか」を制御するものです。
animation-iteration-countで回数を制御する方法と注意点
animation-iteration-count
は、アニメーションの繰り返し回数を指定するプロパティです。
数値
:指定した回数だけアニメーションを繰り返します。例えば3
と指定すれば3回再生されます。infinite
:アニメーションを無限に繰り返します。ローディングアイコンやバナー広告など、継続的に動き続ける表現によく使われます。
<div class="box iteration-example"></div>
.box {
width: 100px;
height: 100px;
background-color: #e74c3c;
animation-name: pulse; /* アニメーション名 */
animation-duration: 1.5s; /* アニメーションの再生時間 */
animation-iteration-count: infinite; /* ★無限に繰り返す */
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
注意点と仕組み
animation-iteration-count
は、animation-duration
で設定したアニメーションの再生時間が終了するたびに、次の再生をトリガーします。infinite
と指定した場合、このトリガーが永久に繰り返されるため、アニメーションが止まることはありません。このプロパティだけでは、繰り返しと繰り返しの間に間隔を空けることはできません。もし間隔を空けたい場合は、後述する@keyframes
のテクニックが必要になります。
@keyframesで「停止→再生」の間隔を作る実例
CSSアニメーションで「動きが止まっている時間」を作るには、@keyframes
内で「状態が変化しない区間」を定義します。これは、animation-delay
のように初回のみ遅延させるのではなく、ループごとに間隔を空けたい場合に有効なテクニックです。
<div class="box keyframes-pause"></div>
.box {
width: 100px;
height: 100px;
background-color: #9b59b6;
animation-name: move-with-pause;
animation-duration: 4s; /* アニメーション全体の時間 */
animation-iteration-count: infinite;
}
@keyframes move-with-pause {
/* 0%から50%まで動く */
0% {
transform: translateX(0);
}
50% {
transform: translateX(200px);
}
/* 50%から100%まで静止 */
51% { /* 50%とほぼ同じ位置から開始 */
transform: translateX(200px);
}
100% {
transform: translateX(200px);
}
}
実際の表示
See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.
このテクニックの鍵は、@keyframes
のパーセンテージ指定にあります。上記の例では、0%から50%の間に動きを定義し、50%から100%の間は同じ状態(transform: translateX(200px);
)を維持するように指定しています。
animation-duration: 4s;
と設定されているため、全体のアニメーションは4秒で1周します。
- 最初の
0%
から50%
までの区間(全体の2秒間)で、要素は左から右へ移動します。 - 次の
51%
から100%
までの区間(残りの2秒間)は、動きがないため、要素は停止したままの状態を保ちます。
このように、@keyframes
内で意図的に「状態が変化しない区間」を設けることで、アニメーションの再生中に「間」を挿入することができます。これは、animation-delay
が初回にしか適用できないのに対し、ループするたびに間隔を空けたい場合に非常に効果的な方法です。
無限ループに「間隔」を持たせるテクニックとサンプルコード

CSSアニメーションで最も頻繁に直面する課題の一つが、無限ループアニメーションに「静止時間」や「間隔」を設ける方法です。単にanimation-iteration-count: infinite;
と指定するだけでは、アニメーションは途切れることなく連続して再生されてしまいます。
ここでは、その課題を解決し、より自然で洗練された動きを表現するための、複数のテクニックと具体的なコード例を紹介します。それぞれの方法にはメリット・デメリットがあり、アニメーションの目的や複雑さに応じて使い分けることが重要です。
@keyframesに「静止時間」を定義する効果的なテクニック
この方法は、アニメーションの動きを定義する@keyframes
内に、意図的に動きのないパーセンテージ区間を作ることで、繰り返しごとの間隔を生み出します。これは、最も直感的で制御しやすいテクニックであり、無限ループアニメーションの定番手法です。
サンプルコード:静止時間を含む点滅アニメーション
<div class="box keyframes-static"></div>
.box {
width: 100px;
height: 100px;
background-color: #2ecc71;
border-radius: 50%;
animation-name: fade-out;
animation-duration: 3s; /* アニメーション全体の時間 */
animation-iteration-count: infinite;
}
@keyframes fade-out {
/* 0%から50%まで透明度が変化する(アニメーション区間) */
0% { opacity: 1; }
50% { opacity: 0; }
/* 51%から100%まで透明度0の状態を維持(静止区間) */
51% { opacity: 0; }
100% { opacity: 0; }
}
実際の表示
See the Pen css-animation-loop-delay-02 by watashi-xyz (@watashi-xyz) on CodePen.
animation-duration: 3s;
と@keyframes
のパーセンテージが重要です。
0%
から50%
:
これはアニメーション全体の時間の半分にあたります。この例では1.5秒かけてopacity
が1
から0
へと変化します。51%
から100%
:
この区間では、開始時と終了時のopacity
がどちらも0
です。つまり、状態に変化がないため、要素は透明なまま静止します。これは残りの1.5秒に相当します。
この手法の最大のメリットは、アニメーションと静止時間の比率を@keyframes
内で自由に調整できる点です。例えば、0%
から20%
で動き、21%
から100%
で静止するといった、動きが短く間隔が長いアニメーションも簡単に実装できます。

animation-durationと@keyframesの比率を調整して間隔を作る方法
前のテクニックと似ていますが、この方法は、アニメーションの動き自体を@keyframes
のごく一部に閉じ込めることで、結果的に長い静止時間を作り出す方法です。特に、動きの時間が非常に短い場合に有効です。
サンプルコード:短時間で動いて長時間停止するアニメーション
<div class="box short-move"></div>
.box {
width: 100px;
height: 100px;
background-color: #f1c40f;
animation-name: shake;
animation-duration: 4s; /* 全体のアニメーション時間 */
animation-iteration-count: infinite;
}
@keyframes shake {
/* 0%〜10%の間で動きを完結させる */
0% { transform: rotate(0deg); }
2% { transform: rotate(5deg); }
4% { transform: rotate(-5deg); }
6% { transform: rotate(5deg); }
8% { transform: rotate(-5deg); }
10% { transform: rotate(0deg); }
/* 11%以降は動きを定義しない */
100% { transform: rotate(0deg); }
}
実際の表示
See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.
この手法では、@keyframes
内のパーセンテージを非常に細かく刻み、動きを全体の時間のごく初期の段階に集中させます。上記の例では、0%から10%の間に要素を揺らす動きを定義しています。animation-duration
が4秒なので、実際の揺れは最初の0.4秒間(4秒 × 10%)で終了します。
残りの11%
から100%
の区間(つまり3.6秒間)は、動きが定義されていないため、要素は最後の状態(transform: rotate(0deg);
)を維持したまま静止します。このテクニックは、短い一瞬の動きを繰り返したい場合に非常に簡潔に記述できるというメリットがあります。
animation-delayを応用してループごとに遅延させる裏技
厳密にはanimation-delay
は初回にしか適用されませんが、これを疑似的にループごとに適用させる「裏技」も存在します。これは主に、複数の要素を時間差で無限ループさせたい場合に有効です。
サンプルコード:複数の要素を時間差で点滅させる
<div class="wrapper">
<div class="dot dot-1"></div>
<div class="dot dot-2"></div>
<div class="dot dot-3"></div>
</div>
.dot {
width: 15px;
height: 15px;
background-color: #34495e;
border-radius: 50%;
display: inline-block;
margin: 0 5px;
animation-name: bounce;
animation-duration: 1s;
animation-iteration-count: infinite;
}
/* 各要素に異なるanimation-delayを適用 */
.dot-1 {
animation-delay: 0s; /* 遅延なし */
}
.dot-2 {
animation-delay: 0.3s; /* 0.3秒遅延 */
}
.dot-3 {
animation-delay: 0.6s; /* 0.6秒遅延 */
}
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-20px);
}
}
実際の表示
See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.
この方法は、アニメーションのサイクル全体を同期させず、各要素の開始タイミングをずらすことで、時間差で動いているように見せるものです。
animation-delay
は初回のみ適用されるため、それぞれの.dot
要素は異なるタイミングでアニメーションを開始します。- 一度アニメーションが始まれば、各要素はそれぞれの
animation-duration
に従って無限ループを続けます。 - 結果的に、常に
0.3s
と0.6s
の遅延をもって次の要素が動き出すように見え、まるでループごとに時間差が生まれているかのような視覚効果を得ることができます。
この裏技は、ローディングアニメーションのドットや、複数の要素が連続して登場するエフェクトなどに応用できます。ただし、一つの要素の無限ループに間隔を空けたい場合には、前述の@keyframes
テクニックを使うべきです。

CSSアニメーションの実践パターン集とエラー対処法

これまで解説してきた基本を応用することで、さまざまな実践的なアニメーションを実装できます。このセクションでは、現場で役立つ具体的なアニメーションパターンと、アニメーションが予期せぬ動きをする際によくある原因と対処法を解説します。
1回だけ再生→止める「非ループ」アニメーションの実装
アニメーションは必ずしもループさせる必要はありません。特定のイベント(例:要素の表示や、ボタンクリックなど)で1度だけ動かしたい場合、animation-iteration-count
を1
に設定し、animation-fill-mode
プロパティを適切に使うことが重要です。
animation-fill-mode: forwards;
アニメーションが終了した後の要素の状態を、アニメーションの最終フレームの状態で維持します。animation-fill-mode: backwards;
アニメーション開始までの遅延時間中、アニメーションの最初のフレームの状態を適用します。
サンプルコード:フェードインして最終位置で停止する
<div class="box single-shot"></div>
.box {
width: 100px;
height: 100px;
background-color: #3498db;
opacity: 0; /* 初期状態を透明に設定 */
animation-name: fade-in-slide;
animation-duration: 1.5s;
animation-iteration-count: 1;
animation-fill-mode: forwards; /* ★アニメーション終了後、最終状態を維持 */
}
@keyframes fade-in-slide {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
実際の表示
See the Pen css-animation-loop-delay-05 by watashi-xyz (@watashi-xyz) on CodePen.
この例では、animation-fill-mode: forwards;
がキモです。もしこのプロパティがなければ、アニメーション終了後、要素はCSSで指定された本来の状態(この場合はopacity: 0;
)に戻ってしまいます。forwards
を指定することで、@keyframes
のto
(100%
)で定義された状態(opacity: 1; transform: translateY(0);
)を維持し、アニメーションが完了した後の不自然な変化を防ぎます。

マウスホバーで無限ループ開始!インタラクティブなアニメーション
ユーザーの操作に応じてアニメーションを開始させることも一般的です。transition
とは異なり、animation
はホバー時に「再生」と「停止」を制御するのに向いています。要素の通常状態ではアニメーションを適用せず、:hover
擬似クラスでanimation
プロパティを適用することで実現します。
サンプルコード:ホバーでアイコンが脈動する
<div class="icon-wrapper">
<span class="pulse-icon">❤️</span>
</div>
.pulse-icon {
font-size: 50px;
display: inline-block;
/* 通常状態ではアニメーションなし */
}
.icon-wrapper:hover .pulse-icon {
animation-name: pulse-anim;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out; /* 動きに緩急をつける */
}
@keyframes pulse-anim {
0% { transform: scale(1); }
50% { transform: scale(1.2); }
100% { transform: scale(1); }
}
実際の表示
See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.
CSSの継承とセレクタの優先順位を利用したテクニックです。初期状態では.pulse-icon
にアニメーションプロパティは適用されていません。しかし、親要素の.icon-wrapper
にマウスがホバーすると、hover
セレクタが有効になり、子要素の.pulse-icon
にアニメーションプロパティが適用されます。マウスが離れると、ホバー状態が解除され、アニメーションも停止します。
バナー広告やローディングで使える「点滅」と「脈動」の作り方
これらのアニメーションは、ユーザーの注意を引きつけたり、読み込み中であることを示したりするのに非常に効果的です。
- 点滅 (Blink):
opacity
を0
と1
の間で変化させることで実装します。 - 脈動 (Pulse):
transform: scale()
で要素の大きさを伸縮させることで実装します。
これらのアニメーションには、animation-iteration-count: infinite;
と、前のセクションで解説した@keyframes
に「静止時間」を含めるテクニックがよく使われます。
<div class="loading-dot"></div>
<p> </p>
<div class="banner-pulse"></div>
/* 点滅アニメーション(ローディングドットなど) */
.loading-dot {
width: 20px;
height: 20px;
background-color: #e67e22;
border-radius: 50%;
animation-name: blink;
animation-duration: 1.5s;
animation-iteration-count: infinite;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.1; }
}
/* 脈動アニメーション(CTAボタンなど) */
.banner-pulse {
width: 150px;
height: 50px;
background-color: #c0392b;
color: white;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
animation-name: pulse-effect;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
@keyframes pulse-effect {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
実際の表示
See the Pen css-animation-loop-delay-07 by watashi-xyz (@watashi-xyz) on CodePen.
これらのコードは、見た目はシンプルですが、animation-timing-function
をease-in-out
にすることで、動きに自然な緩急が生まれ、より洗練された印象を与えます。

無限ループ時に途切れる・不自然になる原因とブラウザ差異への対処法
アニメーションが意図した通りに動かない場合、以下の原因が考えられます。
1. animation-direction
の確認
animation-direction
はアニメーションの再生方向を制御します。
alternate
:アニメーションが往復再生されます(例:0% -> 100%
の次は100% -> 0%
)。normal
:常に順方向(0% -> 100%
)に再生されます。
もし往復させたいのにnormal
のままだと、アニメーションの最終地点から開始地点に急に戻るような不自然な動きに見えることがあります。これは、@keyframes
の100%
から次の0%
への遷移が瞬間的に行われるためです。不自然な動きを防ぐには、animation-direction: alternate;
を使用するか、@keyframes
内で0%
と100%
の両方に同じ値を設定して、動きのない間隔を作るテクニックを使いましょう。
2. アニメーションプロパティの省略記法
animation: name duration timing-function delay iteration-count direction fill-mode;
この省略記法は便利ですが、記述順序を間違えたり、一部のプロパティを省略すると意図しない動作になることがあります。特にdelay
とduration
はどちらもs
やms
で指定するため、最初に書いた値がduration
、次に書いた値がdelay
として解釈されます。
NG例
/* ❌ durationとdelayが意図せず逆転する可能性 */
animation: my-anim 1s 2s infinite;
/* duration: 1s, delay: 2s と解釈される */
OK例(個別指定)
/* ✅ 誤解の余地がないため推奨 */
animation-name: my-anim;
animation-duration: 2s;
animation-delay: 1s;
animation-iteration-count: infinite;
意図した通りに動かない場合は、個別のプロパティで明示的に記述することをお勧めします。
3. ブラウザ互換性(ベンダープレフィックス)
古いブラウザ(特にIEや一部のモバイルブラウザ)では、animation
関連のプロパティにベンダープレフィックス(-webkit-
, -moz-
, -o-
など)が必要な場合があります。
.box {
-webkit-animation: my-anim 2s; /* Chrome, Safari, iOS */
-moz-animation: my-anim 2s; /* Firefox */
-o-animation: my-anim 2s; /* Opera */
animation: my-anim 2s;
}
@-webkit-keyframes my-anim { ... }
@-moz-keyframes my-anim { ... }
@-o-keyframes my-anim { ... }
@keyframes my-anim { ... }
現在はモダンブラウザが主流であるため、必須ではありませんが、広範なサポートが必要な場合はこれらのプレフィックスを含めるのが安全です。Autoprefixer
などのツールを使えば自動的に追加できるため、手動で書く手間を省くことができます。

よくある質問(FAQ)
CSSアニメーションの実装中に、開発者がつまずきやすいポイントや、よく寄せられる疑問についてまとめました。これらの質問と回答が、あなたの悩みを解決するヒントになれば幸いです。
-
CSSアニメーションが途中で途切れる、不自然に動くのはなぜですか?
-
この問題は、主に以下の2つの原因が考えられます。
animation-fill-modeが指定されていない
アニメーションが終了すると、要素は元のCSSで指定された状態に戻ります。アニメーションの最終状態を維持したい場合、animation-fill-mode: forwards;を必ず指定してください。これにより、アニメーションの最後のキーフレームで定義された状態が保持され、不自然なリセットを防ぎます。特に、animation-iteration-count: 1;で1回だけ再生するアニメーションでは、このプロパティが必須です。
@keyframesの0%と100%、そして次のアニメーション開始地点が一致していない
無限ループアニメーションでよく見られる問題です。@keyframesが0%で始まり、100%で終わった後、次のループの0%に瞬間的に戻ることで、ぎこちない動きに見えます。これを解決するには、@keyframesの0%と100%(fromとto)のプロパティ値を同じにするか、animation-direction: alternate;を使用してアニメーションを往復させるのが効果的です。alternateを使えば、100%に到達した後、自然に逆再生されるため、スムーズなループが実現できます。
-
animation-duration
とanimation-delay
を同時に使う際の注意点はありますか? -
animation
プロパティの省略記法を使用する際、記述順序に注意が必要です。animation: <name> <duration> <timing-function> <delay> <iteration-count> <direction> <fill-mode>;
この順序で記述した場合、
<duration>
と<delay>
はどちらもs
やms
といった時間単位で指定するため、ブラウザは最初に書かれた値をduration
、次に書かれた値をdelay
として解釈します。例
- animation: my-anim 2s 1s infinite; → durationが2s、delayが1sと正しく解釈されます。
- animation: my-anim 1s 2s infinite; → durationが1s、delayが2sと解釈されます。
もし誤って記述すると、アニメーションの再生時間と遅延が逆転してしまい、意図しない動きになることがあります。このような間違いを防ぐには、省略記法ではなく、
animation-duration: 2s;
やanimation-delay: 1s;
のように、個別のプロパティで明示的に指定することをお勧めします。
-
JavaScriptを使わずにCSSだけで複雑な繰り返しアニメーションはできますか?
-
はい、多くの複雑なアニメーションをCSSだけで実現できます。以下のテクニックを組み合わせることで、多様な表現が可能です。
複数のanimationを適用する:
一つの要素に複数のanimationプロパティをカンマで区切って記述することで、異なるアニメーションを同時に適用できます。 CSS animation: fade-in 1s forwards, rotate 2s infinite linear; この例では、要素がフェードインしつつ、同時に無限に回転するアニメーションを適用しています。
animation-delay
を時間差で利用する:複数の要素に異なる
animation-delay
を適用することで、一連の動きを時間差で連鎖させることができます。ローディングアニメーションのドットなどが良い例です。@keyframes
のパーセンテージを細かく制御する:@keyframes
内で1%
刻みでアニメーションの状態を定義することで、非常に細かく複雑な動きを作り出すことが可能です。特に、@keyframes
のネストはできませんが、複数のプロパティ(transform
,opacity
,background-color
など)を同時に制御することで、リッチなアニメーションを実現できます。JavaScriptを使えばユーザーとのインタラクションや動的なデータに基づいてアニメーションを制御できますが、静的な繰り返しアニメーションであれば、CSSだけでも十分な表現力を備えています。
-
CSSアニメーションのパフォーマンス
-
CSSアニメーションは、ブラウザのGPU(グラフィック処理ユニット)を活用して高速に描画されるため、JavaScriptによるアニメーションよりもパフォーマンスに優れている点が大きなメリットです。
特に、
transform
,opacity
といったプロパティのアニメーションは、ブラウザがGPUアクセラレーションを適用しやすいです。これにより、メインスレッド(JavaScriptが実行される場所)に負担をかけることなく、スムーズなアニメーションを実現できます。一方で、width
,height
,margin
,padding
といったレイアウトに関わるプロパティは、アニメーション中にページの再描画(リフロー)を引き起こしやすいため、パフォーマンスに影響を与える可能性があります。CSSのみで完結できる場合は、パフォーマンスの観点からもCSSアニメーションを選択することが推奨されます。

まとめ
この記事では、CSSアニメーションの「繰り返し」と「間隔」を自在に制御するためのテクニックを、具体的なコード例とともに解説しました。単にプロパティを覚えるだけでなく、「なぜそのコードが機能するのか」という仕組みを理解することで、予期せぬ挙動にも柔軟に対応できるようになります。
CSSアニメーションは、JavaScriptを使わなくても、ユーザーの目を引くインタラクティブな表現を可能にします。今回学んだ「時間」と「回数」の制御方法をマスターすれば、ローディングアニメーション、ホバーエフェクト、バナー広告など、さまざまな場面であなたのデザインをより魅力的にすることができます。
この記事で得た知識を、ぜひあなたのWeb制作に活かしてみてください。まずは簡単なアニメーションからでも構いません。実際に手を動かしてコードを試すことが、CSSアニメーションを完全に自分のものにする一番の近道です。さあ、あなたも素晴らしいアニメーションの世界へ飛び込みましょう!
あわせて読みたい




