😸

CSSだけでマウスカーソルの座標を取得したいんじゃ!!

2024/12/08に公開

Commune Advent Calendar 2024シリーズ1の 7日目の記事です。

前回の記事
では、正方形の要素を並べて:hoverを使うことでマウスカーソルに追従しているっぽい効果を作ることに成功しました。

でもそれって、現在のマウスカーソルの座標を取得出来ているわけではないので、出来ることが限られているように思います。

もちろん、mousemoveイベントを使えば簡単に座標を取得することは出来るのですが、CSSだけでマウスカーソルの座標を取得することもできそうだと思ったので、今回はそんな私の奮闘記をご覧いただければと思います。

プランA: CSS Counter Stylesを使う

CSS Counter Stylesとは、順序付きリスト要素など、要素の順番を表示するための機能です。

  1. A
  2. B
  3. 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