見出し画像

【CSS】カスタムプロパティをアニメーションしたら面白かった【@property】

この記事はjig.jp Advent Calendar 2023の12月7日(木)の記事です。


こんにちは!
僕は株式会社jig.jpでウェブフロントエンド開発をしている M です。

この記事では CSS のカスタムプロパティをアニメーション化したら面白かった件について紹介します。

アニメーションできそうで、できない時

CSS でアニメーションしようとしたけど思ったように動かない!
といった経験はないでしょうか。

MDN の linear-gradient() から3つ目のサンプルから引用した以下のコードをベースに考えてみます。

<div class="rgb-gradient"></div>
.rgb-gradient {
  width: 300px;
  height: 300px;
  border: solid 2px;
  background: linear-gradient(217deg, rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%),
              linear-gradient(127deg, rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%),
              linear-gradient(336deg, rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%);
}

やりたいこと

.rgb-gradient にホバーしたときに、各 linear-gradient() の軸の方向を + 180deg して グラデーションの終わりを 0% から 70.71% にするアニメーションを作ってみたいと思います。

ちょっと文字だけではわかりづらいので、コードにしてみます!

実験① なにも考えずにやってみる

とりあえず、初期状態とホバー時の background を指定して transition: background 1s; をつけてみました。

.rgb-gradient {
  width: 300px;
  height: 300px;
  border: solid 2px;
  background: linear-gradient(calc(217deg + 0deg), rgba(255,0,0,.8), rgba(255,0,0,0) 0%),
              linear-gradient(calc(127deg + 0deg), rgba(0,255,0,.8), rgba(0,255,0,0) 0%),
              linear-gradient(calc(336deg + 0deg), rgba(0,0,255,.8), rgba(0,0,255,0) 0%);
  transition: background 1s;
}

.rgb-gradient:hover {
  background: linear-gradient(calc(217deg + 180deg), rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%),
              linear-gradient(calc(127deg + 180deg), rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%),
              linear-gradient(calc(336deg + 180deg), rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%);
}

ホバーしてみると状態は変化してくれますが、中間の状態を補間してくれないですね…
どこを補間したらいいのか曖昧なのでしょうか…

実験② カスタムプロパティをアニメーションしてみる

値を変化させたいところをカスタムプロパティに置き換えて、ホバーでカスタムプロパティの値を変化させてみます。
これなら、どこを変化させて補間してほしいのかが伝わるはず…!(伝われ)

:root {
  --angle-offset: 0deg;
  --stop: 0%;
}

.rgb-gradient {
  width: 300px;
  height: 300px;
  border: solid 2px;
  background: linear-gradient(calc(217deg + var(--angle-offset)), rgba(255,0,0,.8), rgba(255,0,0,0) var(--stop)),
              linear-gradient(calc(127deg + var(--angle-offset)), rgba(0,255,0,.8), rgba(0,255,0,0) var(--stop)),
              linear-gradient(calc(336deg + var(--angle-offset)), rgba(0,0,255,.8), rgba(0,0,255,0) var(--stop));
  transition: --angle-offset 1s, --stop 1s;
}

.rgb-gradient:hover {
  --angle-offset: 180deg;
  --stop: 70.71%;
}

…やったか!?

うーん、だめでした。
結果は変わらず、中間の状態を補間してくれないですね。

実験③ おしかった

実はカスタムプロパティのアニメーション自体はできるんです。

そのためには @property 構文を使います。
上のサンプルの先頭の部分を以下のようにしてみます。

修正前

:root {
  --angle-offset: 0deg;
  --stop: 0%;
}

修正後

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

@property --stop {
  syntax: "<percentage>";
  initial-value: 0%;
  inherits: true;
}

すると…

うまくいきました!!これがやりたかったんです!

@property とは一体

@property とは CSS Properties and Values API に含まれているもので、CSS 内でカスタムプロパティの型や初期値、値を継承するかどうかを定義できます。

なんといっても特徴はカスタムプロパティの値をアニメーション的に変えられるところで、これが普通にカスタムプロパティを定義する方法 (実験②) と違うところです。

今回は --angle-offset に対して <angle>、--stop に対して <percentage> という型を指定したため、アニメーションで中間の値が適切に補間されるようになりました!

counter もアニメーションできる!

調べていくと面白い記事を見つけました。
@property を使うと counter による表示もアニメーションできるようです。

Animating Number Counters - CSS - Tricks
https://css-tricks.com/animating-number-counters/

counter とは content と組み合わせることで、連番を表示できるものなのですが、この記事のサンプルではホバーすると勢いよく数字が増えていきます。

ひらがなカウンターで Hello World! してみる

counter で表示できるものは数字だけではなく hiragana というものがあり、値が増えていくにつれて以下のように表示されます。

  • 1 - 48 'あ','い','う','え','お','か','き',…,'ん'

  • 49 - 'ああ’, 'あい’, 'あう',… となります

これが こんにちは と せかい になる値を計算すると…

コードはこちら!

文字列カウンターで Bad Apple!!

既成のカウンタースタイルだけでなく@counter-style を使うと、0 の時は \(^o^)/ 1 の時は /(^o^)\ といったように独自のカウンターを定義できます。

文字列のアニメーションが面白そうだなと思い、画像のピクセルを8点点字に置き換えた文字列と couter を組み合わせたらモノクロのアニメーションが作れるんじゃないかと思いました。

モノクロのアニメーションといえば…
【東方】Bad Apple!! PV【影絵】(https://www.nicovideo.jp/watch/sm8628149)
が真っ先に浮かんだので CSS と 1 個の div タグで再現してみました!

コードはこちら!

@property の対応状況について

Chrome はバージョン 85 (2020年10月) から対応
Safari はバージョン 16.4 (2023年3月) から対応
Firefox はまだ Nightly のようです。
https://caniuse.com/?search=%40property

おわりに

まだ新しい機能なので「積極的に使っていきましょう!」という感じではないですが、他にも面白い表現ができそうなので、みなさんもカスタムプロパティのアニメーションで遊んでみてはいかがでしょうか!

この記事が気に入ったらサポートをしてみませんか?