CSSアニメーションの奥深さを探る:animation-directionと代替方法


値とその動作

  • initial
    ブラウザのデフォルト値にリセットします。
  • alternate-reverse
    アニメーションは、キーフレームの順序、逆順序交互 の順序で再生し、1回完了します。
  • alternate
    アニメーションは、キーフレームの順序と逆順序を 交互 に再生し、1回完了します。
  • reverse
    アニメーションは、キーフレームの 逆順序1回 再生されます。
  • normal (デフォルト)
    アニメーションは、定義されたキーフレームの順序で 1回 再生されます。

応用例

  • 複雑な動き
    複数のアニメーションを組み合わせて複雑な動きを作成
  • 方向転換
    要素を回転させて動きを表現
  • 強調表示
    要素を点滅させて注目を集める
  • ローディングアニメーション
    アニメーション効果でユーザーの待機時間を軽減
  • フェードイン・フェードアウト
    要素を滑らかに表示・非表示する
/* 順方向に1回アニメーションを再生 */
.element {
  animation: my-animation 2s ease-in-out forwards;
}

@keyframes my-animation {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

/* 無限ループで交互に再生 */
.element2 {
  animation: my-animation2 infinite alternate;
}

@keyframes my-animation2 {
  0% { transform: translateX(0); }
  50% { transform: translateX(20px); }
  100% { transform: translateX(0); }
}
  • animation-fill-mode プロパティと組み合わせて、アニメーション開始前後の要素状態を制御できます。
  • animation-iteration-count プロパティと組み合わせて、アニメーションの再生回数を制御できます。


フェードイン・フェードアウト

.fade-in-out {
  animation: fadeInOut 2s ease-in-out;
}

@keyframes fadeInOut {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

ローディングアニメーション

この例では、回転するリングを使用して、ローディングアニメーションを作成します。

.loading {
  animation: loading 1s linear infinite;
}

@keyframes loading {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

強調表示

この例では、要素を点滅させて強調表示するアニメーションを作成します。

.highlight {
  animation: highlight 1s ease-in-out alternate;
}

@keyframes highlight {
  0% {
    background-color: #fff;
  }
  50% {
    background-color: #000;
  }
  100% {
    background-color: #fff;
  }
}

方向転換

この例では、要素を回転させて方向転換するアニメーションを作成します。

.flip {
  animation: flip 2s ease-in-out forwards;
}

@keyframes flip {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(180deg);
  }
}

この例では、2つのアニメーションを組み合わせて、要素を上下に移動しながら回転させる動きを作成します。

.complex-movement {
  animation: movement 2s ease-in-out infinite;
}

@keyframes movement {
  0% {
    transform: translateY(0) rotate(0deg);
  }
  50% {
    transform: translateY(20px) rotate(180deg);
  }
  100% {
    transform: translateY(0) rotate(360deg);
  }
}


JavaScriptを使用する

JavaScriptを使用して、アニメーションの方向を動的に制御できます。この方法は、柔軟性が高く、複雑なアニメーションを作成するのに適しています。

利点

  • ユーザーとのインタラクションに基づいてアニメーションを動的に変更できる
  • 複雑なアニメーションを作成できる
  • 高度な制御が可能

欠点

  • パフォーマンスへの影響が大きい可能性がある
  • CSSアニメーションよりも複雑になる可能性がある
  • JavaScriptの知識が必要


const element = document.querySelector('.element');

element.addEventListener('animationiteration', () => {
  element.style.animationDirection = element.style.animationDirection === 'normal' ? 'reverse' : 'normal';
});

2つのアニメーションを定義する

アニメーションの方向を擬似的に実現するために、2つの個別のアニメーションを定義することができます。1つは順方向、もう1つは逆方向のアニメーションです。

利点

  • 比較的シンプルな実装
  • JavaScriptを使用する必要がない

欠点

  • 複雑なアニメーションには向かない
  • 冗長なコードになる可能性がある


.element {
  animation-name: fade-in, fade-out;
  animation-duration: 2s;
  animation-iteration-count: 1;
  animation-fill-mode: forwards;
}

@keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

@keyframes fade-out {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

CSS変数を使用する

CSS変数を使用して、アニメーションの方向を動的に制御できます。この方法は、比較的新しい方法ですが、柔軟性と簡潔さのバランスを提供します。

利点

  • 変数を使用してアニメーションの方向を動的に変更できる
  • コードが簡潔になる
  • JavaScriptを使用する必要がない

欠点

  • CSS変数のサポートが古いブラウザでは限られている


:root {
  --animation-direction: normal;
}

.element {
  animation: fade 2s ease-in-out forwards;
  animation-direction: var(--animation-direction);
}

@keyframes fade {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

button {
  click: {
    --animation-direction: toggle;
  }
}

アニメーションをトランスフォーメーションと組み合わせる

場合によっては、アニメーションの方向を擬似的に実現するために、CSSのトランスフォーメーションプロパティを組み合わせて使用することができます。

利点

  • シンプルなアニメーションに適している
  • JavaScriptを使用する必要がない

欠点

  • アニメーションの方向を完全に制御できない場合がある
  • 複雑なアニメーションには向かない
.element {
  transform: translateX(0);
  animation: move 2s ease-in-out forwards;
}

@keyframes move {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(200px);
  }
}

button {
  click: {
    element.style.transform = 'translateX(0)';
  }
}