チュートリアル

CSS での色アニメーション:トランジションとキーフレーム

4分で読める

色アニメーションは、ウェブデザイナーに利用可能な最も表現力のあるツールの1つです。ホバーで色合いを移動するボタン、夜明けと夕暮れでグラデーションを周期する背景、エネルギーでパルスするローディングインジケーター—これらの効果は気分を確立し、状態を通信し、単一の JavaScript 行なしでインターフェースに生活を追加します。ただし、CSS の色アニメーションには微妙な点があり、経験のあるデザイナーもトリップアップします。どのプロパティがアニメーション化する、ブラウザーが色の間でどのように補間するか、なぜ一部のトランジションは中点で泥のように見えるか、どのように最新の色空間を使用してスムーズで知覚的に自然な結果を得るか。

このガイドでは、CSS 色のトランジション、キーフレームアニメーション、HSL ベースの色相回転、知覚的な滑らかさのための OKLCH 補間、およびすべてのデバイスでアニメーションをバタバタに保つパフォーマンスの考慮事項について説明します。


CSS 色のトランジション

transition プロパティは、CSS プロパティが変更されるたびにブラウザーに、あるプロパティから別のプロパティにスムーズにアニメーション化するよう指示します。色プロパティ— colorbackground-colorborder-coloroutline-colorfillstroke、その他—すべてアニメーション化可能です。

基本的な構文

.button {
  background-color: #3B82F6;
  transition: background-color 200ms ease;
}

.button:hover {
  background-color: #1D4ED8;
}

カーソルがボタンに入ると、ブラウザーは 200 ミリ秒の間に #3B82F6(Tailwind blue-500)から #1D4ED8(Tailwind blue-700)にアニメーション化します。カーソルが出ると、戻ってアニメーション化されます。

transition 短縮形は受け入れられます:property duration easing-function delay。複数のトランジションはカンマで分けることができます:

.card {
  background-color: #F8FAFC;
  border-color: #E2E8F0;
  transition:
    background-color 300ms ease,
    border-color 300ms ease;
}

.card:hover {
  background-color: #EFF6FF;
  border-color: #BFDBFE;
}

トランジションタイミング関数

イージング関数はアニメーション中の変更率を制御します:

キーワード 動作
ease 遅い開始、速い中央、遅い終了(デフォルト)
ease-in 遅い開始、速い終了
ease-out 速い開始、遅い終了
ease-in-out 遅い開始と終了、速い中央
linear 全体を通じて一定速度
cubic-bezier(x1, y1, x2, y2) カスタムカーブ

色のトランジションの場合、ease-out はしばしば最も自然に感じられます—色はすぐに近似ターゲットに到達して、その後では定住します。物理的な色認識がどのように機能するかと一致しています。

color とマルチプルプロパティのトランジション

すべてのアニメーション化可能なプロパティのトランジションに all を使用できますが、これは他のプロパティが同時に変更される場合、意図しない副作用を引き起こす可能性があります。明示的な方が良いプラクティスです:

.link {
  color: #6366F1;
  text-decoration-color: transparent;
  transition:
    color 150ms ease-out,
    text-decoration-color 150ms ease-out;
}

.link:hover {
  color: #4338CA;
  text-decoration-color: #4338CA;
}

キーフレーム色アニメーション

@keyframes ルールは、連続して再生する可能性のある、指定された回数を繰り返す、またはトリガーで実行できる名前付きアニメーション序列を定義します。トランジションとは異なり、キーフレームは状態変更なしで機能します。ページ読み込みで自動的に実行したり、無限にループできます。

基本的なキーフレーム構文

@keyframes pulse-blue {
  0%   { background-color: #3B82F6; }
  50%  { background-color: #60A5FA; }
  100% { background-color: #3B82F6; }
}

.status-indicator {
  animation: pulse-blue 2s ease-in-out infinite;
}

これにより、#3B82F6(blue-500)と #60A5FA(blue-400)の間で振動するステータスインジケーターが作成され、微妙な呼吸効果が与えられます。

キーフレーム内の複数色ストップ

@keyframes sunrise {
  0%   { background-color: #0F172A; }   /* 深い夜 */
  25%  { background-color: #7C3AED; }   /* 夜明け前の紫 */
  50%  { background-color: #F97316; }   /* 夜明けのオレンジ */
  75%  { background-color: #FDE68A; }   /* 朝の黄色 */
  100% { background-color: #BFDBFE; }   /* クリアな空の青 */
}

.hero-background {
  animation: sunrise 8s ease-in-out forwards;
}

色は #0F172A#7C3AED#F97316#FDE68A#BFDBFEを通じてシフト、映画のような時間帯効果を作成します。

アニメーション プロパティ

animation 短縮形は受け入れられます: name duration timing-function delay iteration-count direction fill-mode play-state

.element {
  /* 名前 | 継続時間 | イージング | 遅延 | 反復 | 方向 */
  animation: pulse-blue 2s ease-in-out 0s infinite alternate;
}

alternate 方向はアニメーションを前に再生してから逆方向にします。終了時のハード飛び込みなしで、スムーズなループを作成します。これは色パルス効果に理想的です。


スムーズな色相回転のための HSL ベースのアニメーション

HSL(色相、彩度、輝度)は、色相が色の車輪の周囲の単一数値で、色相回転を簡潔にします。色相 0 から色相 360 にアニメーション化するとスペクトラムの全色を周期します。

HSL アニメーション用の CSS カスタムプロパティ

最もエレガントなアプローチは、@keyframes と組み合わせた CSS カスタムプロパティを使用しています:

:root {
  --hue: 220;
}

.rainbow-button {
  background-color: hsl(var(--hue) 70% 55%);
  transition: background-color 100ms linear;
}

@keyframes hue-rotate {
  from { --hue: 0; }
  to   { --hue: 360; }
}

.rainbow-button {
  animation: hue-rotate 4s linear infinite;
}

しかし、キャッチがあります。ブラウザーはプロパティ型を知らないため、CSS はデフォルトでカスタムプロパティ値の間で補間することはできません。これが @property が来ている場所です。

アニメーション化されたカスタムプロパティの @property ルール

@property は特定の型で段落的なプロパティを登録し、ブラウザーがスムーズに補間できます:

@property --hue {
  syntax: "<number>";
  initial-value: 0;
  inherits: false;
}

@keyframes hue-rotate {
  from { --hue: 0; }
  to   { --hue: 360; }
}

.rainbow-text {
  color: hsl(var(--hue) 80% 45%);
  animation: hue-rotate 6s linear infinite;
}

@property--hue<number> として宣言すると、ブラウザーは 0 から 360 まで滑らかに補間し、完全な色相車輪をサイクルします。

テーマ効果のための部分的な色相回転

完全な 360 度回転は、興味深い効果を作成する必要がありません。アニメーション化ですより狭い色相範囲は、より抑制され、ブランド上の感情を作成します:

@property --hue {
  syntax: "<number>";
  initial-value: 210;
  inherits: false;
}

@keyframes ocean-shift {
  0%   { --hue: 195; }   /* シアン */
  50%  { --hue: 230; }   /* 青 */
  100% { --hue: 195; }   /* シアンに戻す */
}

.ocean-card {
  background-color: hsl(var(--hue) 60% 45%);
  animation: ocean-shift 5s ease-in-out infinite;
}

これは、青と緑の家族を一度も離れることなく、#00BFCEに匹敵するシアンと #4166CCに匹敵する中程度の青の間でシフト、液体の海のティダル効果を作成します。

彩度と輝度のアニメーション

色相を超えて、彩度と輝度をアニメーション化してパルスを作成できます、フェード、またはエネルギー効果:

@property --lightness {
  syntax: "<percentage>";
  initial-value: 55%;
  inherits: false;
}

@keyframes pulse-light {
  0%, 100% { --lightness: 45%; }
  50%       { --lightness: 65%; }
}

.pulse {
  background-color: hsl(220 70% var(--lightness));
  animation: pulse-light 2s ease-in-out infinite;
}

これにより、青い色合いで優しい明るさのパルスが作成され、通知バッジまたは注意を描き出す要素に理想的です。


知覚的な滑らかさのための OKLCH 補間

HSL ベースのアニメーションは便利ですが、よく知られた問題があります。特定の色合いの間のトランジションの中点は、視覚的に不愉快に見えます—泥のような非飽和グレーゾーンを通じて渡すか、またはデザイナーが意図しなかった中間の色合いを通じて。

これは HSL と sRGB が知覚的に均一ではないために起こります。等しい数値ステップは等しい知覚ステップを生成しません。2つの HSL 色の間のトランジション経路は、エンドポイント間で知覚的に半分の方法にはない中級の色を通じて渡しません。

OKLCH(OK Lightness-Chroma-Hue)これを解決します。等しい数値ステップが等しい知覚ステップを生成するように設計されています。OKLCH 色の間のトランジションは、予期しないグレーゾーンまたは色相シフト特性なしで、スムーズで明るい中点を生成します。

OKLCH でのアニメーション化

@property --oklch-hue {
  syntax: "<number>";
  initial-value: 270;
  inherits: false;
}

@keyframes perceptual-hue-rotate {
  from { --oklch-hue: 0; }
  to   { --oklch-hue: 360; }
}

.smooth-rainbow {
  color: oklch(60% 0.18 var(--oklch-hue));
  animation: perceptual-hue-rotate 8s linear infinite;
}

同じアニメーションを hsl()を使用したのに対して、OKLCH バージョンはローテーション全体を通じて一貫した知覚の明るさを保持しています。黄色、シアン、またはその他の知覚的に非均一な地域を通じて渡すときに、色は暗いまたはペール帯に浸されることはありません。

ダイレクト OKLCH トランジション

OKLCH 補間は、特に2つの特定の色の間の transition に特に強力です:

.button {
  /* From:鮮やかな紫色 [#7C3AED 等価] */
  background-color: oklch(50% 0.22 285deg);
  transition: background-color 400ms ease;
}

.button:hover {
  /* To:鮮やかな青 [#2563EB 等価] */
  background-color: oklch(50% 0.22 255deg);
}

両方の色は同じ OKLCH 輝度(50%)と色度(0.22)を持つため、トランジションは全体を通じて一貫した知覚の明るさと彩度を保持します。sRGB または HSL では、等価のトランジションは中程度で知覚可能に軽くまたは暗くなります。

ColorFYI の Color Converterを使用してあなたのブランド色の OKLCH 等価物を検索してから、アニメーション定義でこれらの値を使用してスムーズな結果を得ます。

OKLCH 補間のある CSS グラデーション

OKLCH はグラデーション品質も改善します。CSS Color 4 では、グラデーションの補間色空間を指定できます:

/* 標準 sRGB 補間—中央に灰色の泥沼領域が表示される可能性があります */
background: linear-gradient(to right, #FF0000, #0000FF);

/* OKLCH 補間—スムーズで知覚的に均一 */
background: linear-gradient(in oklch to right, oklch(60% 0.25 27deg), oklch(60% 0.25 265deg));

in oklch キーワードはブラウザーに OKLCH 空間でグラデーションを補間するよう指示します。これにより、中点全体を通じて認識される明るさを保つと、より豊かな中級の色を生成します。

ColorFYI の Gradient Generatorでベースグラデーションをビジュアルに構築してから、知覚的な均一性のために in oklch を追加してください。

OKLCH での色相補間方向

有用な OKLCH 固有のオプションは、補間が色相の車輪の周囲をどちらの方向で移動するかを制御しています:

/* より短いアーク(デフォルト)—意図しない色合いをスキップする可能性があります */
background: linear-gradient(in oklch to right,
  oklch(55% 0.2 60deg),    /* 黄色オレンジ */
  oklch(55% 0.2 300deg)    /* マゼンタ */
);

/* より長いアーク—明示的に青緑色の領域を移動 */
background: linear-gradient(in oklch longer hue to right,
  oklch(55% 0.2 60deg),
  oklch(55% 0.2 300deg)
);

shorter hue(デフォルト)常に色相の車輪の周りの短いパスを取ります;longer hue はより長いパスを取ります。これにより、グラデーションまたはアニメーションに表示される中間の色合いを制御できます。


パフォーマンスの考慮事項

色アニメーションはブラウザーのレンダリングパイプラインに関与しています。パフォーマンス上の問題がどこで発生するかを理解することで、中程度のモバイルデバイスでもスムーズなままであるアニメーションをデザインするのに役立ちます。

アニメーション用のセーフプロパティ

CSS アニメーションはレンダリングパイプラインのさまざまなフェーズをトリガーします。パフォーマンスの場合、目標は 合成フェーズ に留まる—GPU で処理されます—そして レイアウト または ペイント をトリガーしないようにすることです。

プロパティ パイプラインフェーズ パフォーマンス
transformopacity コンポジッター 優れた
background-colorcolorborder-color ペイント 良い—たまにリペイント
widthheightmarginpadding レイアウト + ペイント 高級—アニメーション化を避ける

色アニメーション(background-colorcolor)は各フレームで リペイント をトリガーします—ブラウザーは影響を受けたエレメントのピクセル色を再計算する必要があります。これは一般的に高速で、最新のデバイスで GPU 加速されていますが、transformopacity アニメーションとしては無料ではありません。

リペイント領域の最小化

リペイント コストは、リペイントされている領域に比例しています。フルスクリーンのヒーロー セクションの背景色をアニメーション化すると、小さなステータスインジケーターよりもはるかに多くのピクセルがリペイントされます。大規模領域の色アニメーションの場合、以下を検討してください:

疑似要素オーバーレイの使用 :静的な背景の上に色付きの疑似要素の opacity をアニメーション化します。opacity はコンポジッターのみで、リペイントをトリガーしません:

.hero {
  position: relative;
  background-color: #1E3A8A;
}

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: #7C3AED;
  opacity: 0;
  transition: opacity 600ms ease;
}

.hero:hover::after {
  opacity: 1;
}

これにより、オーバーレイをフェードインして「色の変更」効果が達成され、コンポジッターレベルの操作のみを使用します。

グラデーント アニメーション制限

標準 CSS は、2つの異なる background-image グラデーント値の間で補間することはできません。2つの linear-gradient() 値の間でトランジションしようとするもし、ブラウザーはスムーズにアニメーション化するのではなくそれらの間にスナップします:

/* これはスムーズにアニメーション化されません */
.element {
  background: linear-gradient(45deg, #3B82F6, #8B5CF6);
  transition: background 500ms ease;  /* スナップ、アニメーション化しない */
}
.element:hover {
  background: linear-gradient(45deg, #EF4444, #F97316);
}

解決策:

オプション1:オーバーサイズ化グラデーションで background-position をアニメーション化

.element {
  background: linear-gradient(45deg, #3B82F6, #8B5CF6, #EF4444, #F97316);
  background-size: 300% 300%;
  background-position: 0% 50%;
  transition: background-position 800ms ease;
}
.element:hover {
  background-position: 100% 50%;
}

オプション2:@property 経由でグラデーション色のストップをアニメーション化

@property --color-start {
  syntax: "<color>";
  initial-value: #3B82F6;
  inherits: false;
}

@property --color-end {
  syntax: "<color>";
  initial-value: #8B5CF6;
  inherits: false;
}

.element {
  background: linear-gradient(45deg, var(--color-start), var(--color-end));
  transition: --color-start 500ms ease, --color-end 500ms ease;
}

.element:hover {
  --color-start: #EF4444;
  --color-end: #F97316;
}

@property がカスタムプロパティを <color> タイプとして宣言すると、ブラウザーは色値の間で補間でき、グラデーションはスムーズにアニメーション化されます。

Will-Change と GPU ヒント

継続的な色アニメーションを持つエレメント(常にパルスするインジケーター、アニメーション化されたバックグラウンド)の場合、GPU リソースを割り当てるようブラウザーにヒントを付けます:

.always-animating {
  will-change: background-color;
}

will-change を控えめに使用—複数のエレメントに同時に適用すると、大量の GPU メモリを消費します。実際に継続的にアニメーション化されるエレメント用に予約してください。

prefers-reduced-motion を尊重

オペレーティングシステムのアクセシビリティ設定で削減されたモーションをリクエストしたユーザー向けに、常にアニメーション化されていないフォールバックを提供します。継続的なアニメーションは、一部のユーザーに悪心と前庭不快感を引き起こす可能性があります:

@keyframes hue-rotate {
  from { --hue: 0; }
  to   { --hue: 360; }
}

.animated-element {
  animation: hue-rotate 4s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .animated-element {
    animation: none;
    /* オプションで特定の静的な色を設定 */
    background-color: hsl(220 70% 55%);
  }
}

これは単なるベストプラクティスではありません— WCAG 2.3 AA 適合に必須です(成功基準2.3.3相互作用からのアニメーション)。


重要なポイント

  • CSS 色のトランジション は、ホバー、フォーカス、またはクラス変更時の色状態間をアニメーション化するために transition プロパティを使用します;すべての色プロパティ— background-colorcolorborder-color など—がアニメーション化可能です。
  • @keyframes は、継続的にループするマルチステップの色アニメーション、指定された回数で実行する、またはトリガーに応答して可能にし、各ステップでイージングとタイミングの完全な制御を持ちます。
  • HSL ベースの色相回転 は、スペクトラムアニメーションに便利です—色相度を 0 から 360 にアニメーション化は、完全な色の車輪をサイクルします。ブラウザーがそれらをスムーズに補間するように、カスタムプロパティを型付き値として宣言するために @property を使用します。
  • OKLCH は HSL または sRGB よりもはるかに知覚的にスムーズな色のトランジションを生成します。等しい OKLCH ステップが等しい知覚ステップを生成するため—泥のような灰色の中点またはズレた色合いなし。ブランド色の OKLCH 値を見つけるために Color Converterを使用してください。
  • グラデーション宣言で in oklch を使用します(linear-gradient(in oklch ...))、知覚的に均一なグラデーション補間で、全体を通じて一貫した明るさを持つために。
  • CSS 異なる linear-gradient() 値の間で補間することはできません 。ネイティブに;<color> タイプのカスタムプロパティで @property を使用するか、オーバーサイズ化グラデーションで background-position をアニメーション化するのワーカラウンドとして使用します。
  • 色アニメーション レイアウト変更ではなくリペイント をトリガー —一般的に高速ですが、大規模なサーフェスアニメーションのリペイント領域を最小化するために、不透明度ベースのオーバーレイの手法またはコンポジッターのみの代替案を使用します。
  • 前庭またはモーション感度の障害を持つユーザーのための継続的なアニメーション を無効化する @media (prefers-reduced-motion: reduce) オーバーライドを常に含めます。
  • ColorFYI の Gradient Generatorを使用してアニメーション化されたグラデーションの色のストップをビジュアルに構築してから、最も滑らかなオンスクリーン結果のために in oklch 補間で改善してください。

関連カラー

関連ブランド

関連ツール