2 ポイント 投稿者 GN⁺ 2024-09-05 | 1件のコメント | WhatsAppで共有
  • CSS @property が最新ブラウザー全般でサポートされるようになり、カスタムプロパティに 構文・初期値・継承の有無 を明示でき、ブラウザーが値を自然に補間できるようになった
  • 例の CTA ボタンでは --gradient-angle<angle> として定義し、0deg から 360deg まで遷移させ、conic-gradient回転する光沢のあるボーダー を作っている
  • ホバー効果は --gradient-percent--gradient-angle-offset--gradient-shine のようなプロパティに型を与え、光沢の長さと明るさ が滑らかに変わるよう構成されている
  • 回転速度は同じアニメーションを 2 回宣言し、2 つ目を 逆方向・一時停止 状態にしておき、ホバー時に現在位置から半分の速度まで遅くなるようにしている
  • @property ベースのカスタムプロパティ定義は、以前は実装が難しかった CSS 表現を可能にし、大規模アプリケーションやデザインシステムにも活用の余地が大きい

@property が開くカスタムプロパティアニメーション

  • @property は、CSS カスタムプロパティに 許可される構文初期値継承の有無 を明示するルール
  • CSS Houdini の CSS Properties and Values API と結びついた機能で、最近ではすべての最新ブラウザーでサポートされている
  • ブラウザーがカスタムプロパティの型を把握できれば、値どうしを補間できるため、通常の CSS 変数だけを使う場合よりも滑らかな遷移やアニメーションを作りやすい

CTA ボタンの回転する光沢ボーダー

  • 例では、Web でよく見かけるきらめく CTA ボタン スタイルを CSS で実装している
  • 中核となるカスタムプロパティは --gradient-angle で、@property<angle> 構文と 0deg の初期値を宣言する
@property --gradient-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
  • この定義により、ブラウザーは 0deg から 360deg まで自然に遷移し、conic-gradient が回転しているようにレンダリングする
@keyframes rotate-gradient {
  to { --gradient-angle: 360deg; }
}

.rotate-gradient {
  background: conic-gradient(from var(--gradient-angle), transparent, black);
  animation: rotate-gradient 10s linear infinite;
}
  • CodePen デモ で、この概念を最小限のコードで確認できる

背景レイヤーで作るボーダーの光沢

  • 光沢ボーダーは linear-gradientconic-gradientbackground に一緒に入れ、それぞれの背景の原点を変えて作る
    • linear-gradientpadding-box を使うため、ボーダー領域にはみ出さない
    • conic-gradientborder-box を使うため、ボーダー幅によってできた領域まで広がる
    • 1px の透明ボーダーを追加することで、回転する conic-gradient が見えるようになる
.border-gradient {
  background:
    linear-gradient(black, black) padding-box,
    conic-gradient(from var(--gradient-angle), transparent 25%, white, transparent 50%) border-box;
  border: 1px solid transparent;
}

ホバー時に滑らかに変わるグラデーション

  • ホバー遷移に必要な各カスタムプロパティごとに @propertysyntax を宣言し、ブラウザーが値の変化を 補間 できるようにする
  • ボタン背景は、内側の色を担当する linear-gradient と、ボーダーの光沢を担当する conic-gradient で構成される
  • --gradient-percent は光沢領域の大きさを決め、ホバー時にはより大きいパーセンテージに変わることで光沢の長さが伸びる
  • --gradient-angle-offset は、ホバー中に光沢が前後に跳ねて見えないよう、グラデーションの角度を再調整するために使われる
  • --gradient-shine の明るさは、周囲のハイライト色とより自然に混ざるよう低めにされる

ホバー中に回転速度を落とす方法

  • 回転速度を遅くする CSS のコツは、同じ回転アニメーションを 2 回宣言すること
  • 2 つ目のアニメーションは 逆方向 にし、継続時間を半分に分け、デフォルト状態では paused に設定する
  • ホバー時には animation-play-state: runningpaused を上書きし、回転を半分の速度まで遅くする
  • ホバーが終わると、アニメーションは開始位置へ跳ね戻ることなく、現在位置から再び速くなる
  • CTA ボタンのアニメーションはこの方法を使い、回転と動きが速度を変えても噛み合うようにしている

小さなきらめきと内部ハイライト

  • ボタン内部の小さなドットパターンは、::before 疑似要素に radial-gradient 背景を作ってレンダリングする
  • --gradient-angle はここでも再利用され、conic-gradient マスクが回転しながらドットパターンの一部だけを見せる
  • マスクのグラデーション角度は、光沢ボーダーの回転に合わせるため 45deg オフセットされる
.shiny-cta::before {
  mask-image: conic-gradient(
    from calc(var(--gradient-angle) + 45deg),
    black,
    transparent 10% 90%,
    black
  );
}
  • ::after 疑似要素には、ハイライト色を含むグラデーションを追加し、光沢領域と一緒に回転するようにする
  • 内部ハイライトが、ボタン内側を流れる光のような印象を加える

ホバー時の色と仕上がりの調整

  • ボタンの ::before::after がすでに使われているため、ボタンテキストは span で包む
  • span の疑似要素の 1 つには、ハイライト色を含むぼかした box-shadow を適用し、ボタンのサイズまで広げる
  • ホバー時、この疑似要素はゆっくり大きくなってから縮み、穏やかな呼吸のような感覚を作る
  • 内部で回転するハイライト色と組み合わせることで、CTA ボタンの最終効果を完成させる

デザインシステムへつながる可能性

1件のコメント

 
GN⁺ 2024-09-05
Hacker News の意見
  • Web 開発者ではないものの、フレームワークなしでおもちゃの Web サイトを作ったり、いくつかの Web フレームワークで基本的な作業をしたことはありますが、CSS が出始めた頃は、少し経てば全部頭に入れて使えるものでした
    最初の CodePen の例にある CSS は、ほとんど判読できない難解な構文のように見えますし、スタイルシステムの中に小さなアニメーション用プログラミング言語まで必要なのか疑問です
    これは JavaScript でできることではないかと思いますし、JS を何にでも使うことへの反感は理解できますが、それでもプログラミング言語ならこういうことは本業に近いように見えます

    • その感覚がよく分かりません。Web 開発者、特にフロントエンド開発者でなければ、こうした派手な効果の入った HTML 要素を作ることもあまりないはずなのに、CSS が高度な機能で何をできるかがなぜ問題になるのか分かりません
      JavaScript でも当然可能ですし、canvas を置いて WebGL で GPU 上で効果をプログラミングすることもできます。その代わり、HTML ボタンのアクセシビリティ機能をすべて自分で作り直す必要があり、それがより簡単かは疑問です
    • 性能のためです。JS でやると秒間 60 回、途切れずに実行される必要がありますが、JS はシングルスレッドなのでメインスレッドが詰まった瞬間にフレームを落とします
      最新の JS エンジンはすごいとはいえ、ネイティブコードほど効率的ではないため CPU 使用量が増え、結局バッテリー寿命にも良くありません
    • サイトで JavaScript を避けられる機会があるなら、手間が増えても歓迎します。JavaScript をオフにして使う訪問者は、今日の Web を悩ませる多くのエクスプロイトやトラッカーを避けられます
      同じ理由で、JavaScript が必須でないサイトはありがたいと思います
    • ページの見た目にだけ関わることのために、完全なプログラミング言語が必要になるのは良い考えではありません
      一部のホスティングプラットフォームは、セキュリティ上 HTML と CSS の個人化は許可する一方で JS はブロックします。Itch.io のようにゲームやプロフィールを装飾できる場所がそうで、CSS アニメーションを使えば JS のアクセス権を与えなくても見栄えのする効果を作れるので、妥当で有用です
    • 問題領域をよく理解しておらず、構文も知らない状態で、すぐ理解できないものを否定的な変化と見ているように思えます
  • この記事を読んでいて、見慣れない概念に脳が抵抗している感じがしました。ブログの例を見る前に、最初の文にリンクされている MDN の記事を先に読むことをおすすめします
    @property は自分で触ってみて初めて感覚がつかめそうですし、複雑な UI を実装しながら JS への依存を減らしたいなら、こうした難解な CSS 機能を知っていることは強力な武器になります

    • MDN の記事を読んでもまったく理解できません。これは文字どおり CSS 変数なのでは、と思います
      CSS 変数もカスケードされてクラスなどで上書きできましたし、Tailwind の bg-opacity のようなものもそういう仕組みではないかと思います
    • 私も似た感じです。この記事は説明が本当に下手だと思います
      MDN を見ると、以前の CSS 変数とほぼ同じですが、特定の要素や子要素にスコープが限定され、角度・パーセントのような CSS 単位を認識する制約が追加されたものに聞こえます
      それでも使う気はしません。この程度の小さな利点では複雑さと互換性コストを正当化できませんし、不要な新構文は避けるようにしています。CSS 変数以降、CSS の新機能にはかなり興味が薄れました
    • 自分だけかと思っていましたが、本当に見慣れない感じがします
      CSS の transform を使うことに比べて、どんな利点があるのかよく分かりません
  • CSS 作業は好きですが、CSS を難しく感じる同僚とも仕事をしている立場から、Kevin Powell の YouTube チャンネルを強くおすすめします
    この機能を何度か扱っていて、1 週間前に公開した動画では、登録済みプロパティによって可能になる便利な機能を 1 つ見せています: https://youtu.be/U8NykwZNbGs
    登録済みプロパティを追いやすい例で解説した記事もあります: https://moderncss.dev/providing-type-definitions-for-css-wit...

  • 最近の CSS の取り組み、特に Houdini には期待しています。IE 5.5 の機能本を見たとき以来、こういう感覚は久しぶりです
    この 14 年間で CSS には多くの新機能が追加されましたが、新しいレイアウトオプションや変数のように、スタイルフレームワークなら期待される基本機能に近いものでした
    ところが IE の開発者たちは本当に大胆で、JS コードをモジュールにして CSS から要素に紐づけることもできました。ついにそうした過激な機能が戻ってくる感じがします
    例: https://developer.chrome.com/docs/css-ui/houdini

    • ここで「大胆」という表現を肯定的に使っているのか否定的に使っているのか、よく分かりません
    • それは css3pie(http://css3pie.com/) が動いていた仕組みではなかったかと思います
  • 短くて良い記事です。もっと多くの例、特にずっと単純で感覚を早くつかみやすい例を見たいなら、古い CSS-Tricks の記事をおすすめします
    2021 年の記事ですが、今でも有効でよくできています: https://css-tricks.com/exploring-property-and-its-animating-...
    特に空港の数字/タイマーがめくれるフリップディスプレイの例は気に入ると思います

  • しばらくWeb開発から離れていたので、この機能が実際に何をするのか理解するのにかなり時間がかかった。記事の説明があまりうまくない気がする
    私の理解では、360deg のような生の値の代わりに from var(--gradient-angle) のように書き、その値は @property --gradient-angle {...} ブロックで定義した場所から取ってきて置き換えられる
    inherits: false; もあるが、動作自体は分かるものの、なぜ必要なのかは分からない。CSSセレクターで既に継承を制御できるのに、今度は別の場所でも制御できるということなのか、追いかけるのが難しい
    さらに、なぜ @property ブロックでを定義しなければならないのかも疑問。CSSの他の場所では型を定義しないのに、ブラウザが @property が使われている位置を見て推論できないのかと思う

    • 私にとって最大の利点は、この機能で CSS変数をアニメーションできることだった
      以前、YouTubeのデザインをネオン風に変える実験で、主要な色を単一のCSS変数で制御するようにし、その色相をスペクトル全体にゆっくり動かした
      @property なしではCSS変数をアニメーションできないので、単に生の値の代わりに変数を使うだけでなく、その変数と、その変数が参照されるすべての場所をまとめてアニメーションできるようになる。@keyframes neon-flow { from { --dc-neon-hue: 0; } to { --dc-neon-hue: 360; } } ひとつで、主要な色や影などを全部動かせる
      inherits: false は、カスタムプロパティがどのように継承されるかを制御する。color: red のように子に継承させることもできるし、display: flex のようにその要素だけに適用させることもできる
      型は、静的な時点で何をアニメーションするのかを知るために必要そうに見える。CSS変数は何にでもなり得るが、通常のCSSプロパティは color のようにプロパティ自体が型情報を与えるから
      面白いのは、この型構文がMDNで見る正式な構文と同じだという点: https://developer.mozilla.org/en-US/docs/Web/CSS/color#forma... CSSの内部を、開発者が使えるAPIとして公開した感じがする
    • CSSプロパティ自体は @property 以前からあり、例えば --my-prop: 10px を宣言してから var(--my-prop) で他の場所で使うことはできた
      新機能である @property は、プロパティをあらかじめ定義して、どの構文型を受け入れるべきか、親の値を継承するか、デフォルト値である initial-value を何にするかを決められるようにするもの
      そのため、角度型として宣言されたプロパティに、ある要素が --my-prop: 5px を入れると無視される。以前は有効な値になり、使われる場所によって意図しない副作用が起きる可能性があった
      また、--my-prop: initial のように書けば、正確なデフォルト値を知らなくても initial-value を使わせることができる
    • この説明はありがたい。記事が @property が何をするのか、どう使うのかを説明していないのは理解しづらい
      過度に複雑な例のせいで完全に隠れてしまっている
  • このWebサイトを見て気分がよくなった
    もともとCSSをいじるのが好きだったが、10年以上Web開発をしてWeb関連の仕事を職業にする中で、人々がCSSをどれほど嫌っているかも知るようになった
    手書きのHTML+CSSを探索したり実験したりするのにいくらでも時間を使えるし、実際のスマホでどんな感じかを見るためにデプロイまでしてみる。その99%はどこにも使われない
    ほとんどの人にとっては時間の無駄だろうが、このサイトは本当に一日を楽しくしてくれた

    • CSSが本当に好き。理解するのも十分簡単だと思う
      この10年で複雑にはなったが、10年前にやっていたことは今ではずっとシンプルにできるし、その頃のコードもまだ動く
    • CSSが嫌いだと大声で言う人たちは、たいてい CSSを理解していない人たち
      それでも問題ない。私もAPEXやAPL、今日の最新フレームワークは理解していない。でもCSSは理解しているし、だからかなり楽しんでいる
      ある人にはピンと来て、ある人には来ない。問題は、CSSが合わない人が仕事上CSS作業をしなければならないときに起き、当然嫌いになる。私の仕事がActive Directoryのインストールを保守しろというものなら、私も嫌になるだろう。でもCSS自体が悪いわけではない
    • CSSは遊ぶのが楽しく、新機能も探索する価値がある。ただ、CSSの機能はしばしば「次は何を作れるだろう?」という雰囲気から出てきているように感じる
      どこかには真剣な議論が交わされているフォーラムがあるのだろうが、私は見逃しているようだ
    • まだかなりミニマルではあるが、BootstrapやTailwindのようなツールの外で作業する感覚を得るために、手書きのCSSをもっと書いているところ
      本番では特に、フロントエンドはほぼすべてJSXで書いてきたが、Webスクレイピングの沼にはまってから、セレクターロジックの理解がかなり深まった
      関連する挑発的な考えとして、実務でセマンティック要素をもっと多く使っていれば、セレクターロジックは今ほど厄介ではなかったのではないかと思う。モーダルのように純粋なHTMLが既に定義している動作も、自分で保守しなくて済む
    • 自分の特定のデバイス・画面・ブラウザ・ブラウザバージョン・OSの組み合わせだけを扱うのではなく、かなり広くサポートされるものを実装しなければならない瞬間、微妙な仕様違反が本当に腹立たしい
      昔はMicrosoftが最も悪名高い仕様違反者で、今はAppleがそうだと思う
  • これらのアニメーションは、すべてを2000年代のディスプレイ広告のように見せている。悪い意味でそうだ
    こういう美意識が流行らないことを本当に願う

    • 私も同じ。CodePenの例をCSSだけでできるというのは興味深かったが、少しやりすぎだと感じたし、最初のCTAボタンを実際のWebサイトで見たら、ダサくて気恥ずかしいと思ったはず
      こういうものはマーケティングと操作の感じが強い。サイトを読んで、自分が何をするか決めさせてほしい。金になる要素へ無理やり視線を引きつけて邪魔しないでほしい
    • 最初はCodePenが私にアップセルしようとしているのかと思った
    • こういうものは既にネイティブアプリのコードでやっていることなので、Webにも対応する機能があるべき
      そうでなければ、皆がクローズドなエコシステムの中で実装することになる
  • PFM、つまり「純粋な魔法」という表現は、CSS アニメーションで可能なことを見たときにまさに感じるもの
    ただし CSS と CSS のためだけにあまりにも特化しているので、JS で手続き的に実装するよりも学習したり概念化したりするのが難しい。そういう考え方にうまくなじめず、CSS の flex の使用オプションだけでも十分に手いっぱい

    • CSS は本当に独自の異界のようなもの。ほとんどの開発者にとって構文がなじみにくいことも助けにならない
      とはいえ強力で、本当にとてつもなく強力で、ほとんどのブラウザで非常に効率的。Web アプリ開発者の圧倒的大多数には CSS が提供するものの 99% は必要ないが、そうした機能があると知っているのは素晴らしい
    • そこで HTML+CSS をコーディングできるデザイナーを雇った
      ビジネスロジックにつながったスタイルなしの要素をページに置いておけば、デザイナーが望むようにスタイリングできる。必要なら後で UI の調整を繰り返せばよい
    • SQL と同じ宣言型パラダイム
      純粋に命令型の観点から見ると、仕様を読んで試す時間が少し必要だが、SQL と CSS を使う以上の価値がある考え方だと思う。もちろん SQL と CSS 自体にも十分な価値がある
    • JS はいつでも、本当にいつでも最後の手段。ここ数年で CSS の機能がほとんどのブラウザに入ったことで、コードから JS をかなり取り除き、ページを JavaScript Zero にするのが好き
      CSS の “masonry” 機能の名前[1]さえ決めて、スクリプトなしで使えるようにしてくれたら、とても嬉しいと思う
      [1] https://github.com/w3c/csswg-drafts/issues/9733
    • この場合、propertyCSS Houdini API の一部で、JavaScript から CSS を以前よりはるかに強力に操作できるようにするもの
      https://developer.mozilla.org/en-US/docs/Web/API/Houdini_API...
  • 筆者が新しい CSS の断片に示している熱意は、ほぼ 10 年ぶりに見るレベルで、それがとても良い
    20 代だったら、この機能の可能性を何時間も、何日もいじり回していただろう。CSS で何かを動かせるようにするのは楽しかった
    今では flexboxgrid、そしてほとんどの Web サイトやアプリが標準的なデザイン原則に従っているおかげでかなり簡単になり、Web UI はほとんど解決済みの問題に近くなったと思う

    • その標準的なデザイン原則が何なのか気になる
    • 何が解決されたというのか分からない。レイアウトのことか?
      いまだに flexgrid の曖昧な部分を読み直さなければならないことがある。sticky の位置指定は最も便利な機能の一つだが、何らかの理由で動かないと、デバッグして原因を理解するのが非常に難しい、あるいはほとんど不可能。親要素のどこかに overflow があるか、といった問題もある
      こうしたエッジケースをうまく説明するドキュメントも見つけにくく、開発者ツールなしにソースコードだけで CSS をデバッグするのはほぼ不可能なので、実行時に要素を検査する必要がある
      ほとんどのネイティブ入力要素はいまだにスタイリング可能性が非常に限られており、ネイティブのモーダルやポップオーバーも何年も待たされた。最後に確認したときは、まだ display: none から block へ高さをアニメーションすることもできなかった
      CSS のさまざまな問題に慣れすぎて、批判意識がなくなっているのではないかと思う