CSS @propertyでカスタムプロパティにアニメーションをかけてみた

2026.04.14 09:00
2026.03.16 13:33
CSS @propertyでカスタムプロパティにアニメーションをかけてみた

CSSカスタムプロパティ(CSS変数)って便利ですよね。でも、transitionanimationでスムーズに変化させようとすると、うまくいかないんですよね。

今回は、CSS @property を使ってカスタムプロパティにアニメーションをかける方法を試してみました。

サンプルページを見る(グラデーション色変化・回転・カウントアップのインタラクティブデモ)

CSS変数は通常トランジションできない

まず、普通にCSS変数をtransitionで変化させようとしてみます。

:root {
  --bg-color: #3498db;
}

.box {
  background: var(--bg-color);
  transition: --bg-color 0.5s ease;
}

.box:hover {
  --bg-color: #e74c3c;
}

これだと、ホバーしても色がパッと切り替わるだけで、スムーズなアニメーションにはなりません。ブラウザはCSS変数の中身がどんな型の値なのか分からないので、補間(中間値の計算)ができないんですよね。

@propertyで型を定義するとアニメーション可能になる

@propertyは、CSSカスタムプロパティに「型情報」を与える仕組みです。もともとCSS Houdiniの仕様から生まれたもので、型が分かればブラウザが中間値を計算できるようになります。

書き方はこんな感じです。

@property --bg-color {
  syntax: "<color>";
  inherits: false;
  initial-value: #3498db;
}

3つのディスクリプタを指定します。

  • syntax: プロパティの型を定義します。<color><length><number><angle><percentage>などが使えます
  • inherits: 親要素から値を継承するかどうかです。trueまたはfalseを指定します
  • initial-value: 初期値です。syntaxで指定した型に合った値を書きます

この3つはすべて必須です。どれか一つでも抜けるとエラーになるので注意ですね。

実例1: グラデーションの色をアニメーション

通常、background: linear-gradient(...)はトランジションできません。でも@propertyを使えば、グラデーション内の色をスムーズに変化させられます。

@property --gradient-start {
  syntax: "<color>";
  inherits: false;
  initial-value: #3498db;
}

@property --gradient-end {
  syntax: "<color>";
  inherits: false;
  initial-value: #2ecc71;
}

.gradient-box {
  background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end));
  transition: --gradient-start 0.8s ease, --gradient-end 0.8s ease;
}

.gradient-box:hover {
  --gradient-start: #e74c3c;
  --gradient-end: #f39c12;
}

ホバーすると、青→緑のグラデーションが赤→オレンジにスムーズに変わります。グラデーション自体はtransitionできませんが、中の色を個別に@propertyで定義してあげることで解決できるんですよね。

実例2: 角度を変えてグラデーションを回転

角度も@propertyで型定義すれば、アニメーションできます。グラデーションをぐるぐる回転させてみました。

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

.rotating-gradient {
  background: conic-gradient(from var(--angle), #f06, #9f0, #0ff, #f06);
  animation: rotate-gradient 3s linear infinite;
}

@keyframes rotate-gradient {
  to {
    --angle: 360deg;
  }
}

conic-gradientの開始角度を@propertyで定義して、@keyframesで0degから360degまで回しています。これだけでグラデーションがくるくる回転するアニメーションが作れます。CSSだけで実現できるのが良いですね。

実例3: 数値のカウントアップアニメーション

<integer>型を使うと、数値のカウントアップも@propertyで実現できます。JavaScriptを使わずにCSSだけで数値をカウントアップさせてみました。

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

.counter {
  animation: count-up 2s ease-out forwards;
  counter-reset: num var(--num);
}

.counter::after {
  content: counter(num);
}

@keyframes count-up {
  to {
    --num: 100;
  }
}

ポイントはcounter-reset--numの値をCSSカウンターに渡しているところです。@property<integer>として定義しているので、0から100まで整数で補間されます。結果として、画面上で数字が0から100にカウントアップしていくアニメーションになります。

ブラウザ対応状況

@propertyのブラウザ対応状況をまとめてみました(2026年3月時点)。

  • Chrome: 85以降で対応
  • Edge: 85以降で対応
  • Safari: 15.4以降で対応
  • Firefox: 128以降で対応

主要ブラウザはすべて対応済みですね。Firefoxの対応が2024年と比較的最近ですが、現在はほぼ問題なく使えます。

@supportsでフォールバックを用意する

とはいえ、古いブラウザも考慮する場合はフォールバックを用意しておくと安心です。@supportsを使って、@propertyに対応しているかどうかを判定できます。

/* フォールバック: 通常のトランジション */
.box {
  background: #3498db;
  transition: background 0.5s ease;
}

.box:hover {
  background: #e74c3c;
}

/* @property対応ブラウザ向け */
@supports (background: paint(something)) {
  @property --bg-color {
    syntax: "<color>";
    inherits: false;
    initial-value: #3498db;
  }

  .box {
    background: linear-gradient(135deg, var(--bg-color), #2ecc71);
    transition: --bg-color 0.8s ease;
  }

  .box:hover {
    --bg-color: #e74c3c;
  }
}

非対応ブラウザでは単色のtransitionでフォールバックしつつ、対応ブラウザではグラデーションのアニメーションを楽しめるようにしています。

ただし、@supports@propertyを直接検出する標準的な方法はまだ確立されていません。上記のpaint()を使った判定はCSS Houdiniのサポート状況をおおまかにチェックするものです。より確実にやるなら、JavaScriptのCSS.registerPropertyの存在チェックと組み合わせるのも手ですね。

if (CSS.registerProperty) {
  document.documentElement.classList.add('supports-at-property');
}
/* JSで付与したクラスを使ったフォールバック */
.supports-at-property .box {
  background: linear-gradient(135deg, var(--bg-color), #2ecc71);
  transition: --bg-color 0.8s ease;
}

まとめ

CSS @propertyを使うことで、今まで不可能だったカスタムプロパティのアニメーションができるようになりました。特にグラデーションのアニメーションや数値のカウントアップなど、以前はJavaScriptが必要だった表現がCSSだけで実現できるのは嬉しいですね。

  • CSS変数は型情報がないのでそのままではアニメーションできない
  • @propertysyntaxinheritsinitial-valueを定義すると補間が可能になる
  • <color><angle><integer>など様々な型が使える
  • 主要ブラウザは対応済みだが、フォールバックも用意しておくと安心

サンプルページで実際の動きを確認する

今回は以上です!