CSSだけでマウスカーソルの座標を取得したいんじゃ!!
Commune Advent Calendar 2024シリーズ1の 7日目の記事です。
前回の記事
では、正方形の要素を並べて:hoverを使うことでマウスカーソルに追従しているっぽい効果を作ることに成功しました。
でもそれって、現在のマウスカーソルの座標を取得出来ているわけではないので、出来ることが限られているように思います。
もちろん、mousemoveイベントを使えば簡単に座標を取得することは出来るのですが、CSSだけでマウスカーソルの座標を取得することもできそうだと思ったので、今回はそんな私の奮闘記をご覧いただければと思います。
プランA: CSS Counter Stylesを使う
CSS Counter Stylesとは、順序付きリスト要素など、要素の順番を表示するための機能です。
- A
- B
- C
のような要素番号を表示するときに使います。
counterは変数のように宣言し、
.section {
counter-increment: section; // .section要素が表示されるとsectionカウンターの値が+1される
}
というように要素をカウントしていきます。
おそらくDOMツリーを先行順に走査するような処理になっているはずです。
詳しくは CSS Counter Styles - MDNを読んでみると良さそうです。
カウンターはincrementだけでなく、任意の固定値を代入することも可能です。
.item {
counter-set: item 100; // item カウンターに100を代入
}
実際にやってみた
で、これをどう使うのかですが、以下のような方針で考えました。
- 領域いっぱいに正方形要素を敷き詰める
- 正方形毎にその座標を示す custom propertyをsetしておく
- 正方形がhoverしたときに、custom propertyに基づいて counterをセットする
- 最後にcounterの値(x,y座標)を表示する
という感じです。
そして実際に実装した例が以下です。
結構ちゃんと動いてますね。ただし、100x100ならば問題なさそうですが、画面フルサイズにするとかなり処理が遅くなります。
それもそのはず、正しくcountするためには多数の要素を走査することになるので、パフォーマンスはどうしても悪くなってしまいます。
また、CSS Counterはcontentで扱うことができてもCSS Custom Propertyとして扱うことができないので、表示させるだけで、何かを制御することはできません。
というわけで、別の実装案もためしてみましょう。
プランB :has()を使う
別プランとして思いついたのは疑似クラス:hasを使うパターンです。
以下のように実装することが出来ました。
このパターンでも一応動作はするのですが、プランAとくらべても遥かに動作パフォーマンスが悪いです。
また、この実装をする場合はSASSを使って大量にCSSクラスを定義してする必要があります。
そのため、ランタイムパフォーマンスだけでなくビルドパフォーマンスにも影響を与えてしまい、あまり実用的ではないように思います。
まとめ
CSSだけでマウスカーソル座標を取得することは不可能ではないですが、すなおにmousemoveイベントを使ったほうが良さそうです。
Discussion