【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
おわりに
まだ新しい機能なので「積極的に使っていきましょう!」という感じではないですが、他にも面白い表現ができそうなので、みなさんもカスタムプロパティのアニメーションで遊んでみてはいかがでしょうか!
この記事が気に入ったらサポートをしてみませんか?