きっと10年後も同じ想い

茨城で震度4の地震。 この辺りは震度2とのことだが、全く気付かなかった。

仕事で、ちょいちょい長い待ち時間ができる。 待ってる間に他の作業をやっているとメモリ不足で死んだりするので、本当にただ待っているだけの時間。

そんな待ち時間にふと思いついた、テーブルでマウスカーソルがある行と列の色を css だけで変える方法について。

行は簡単にできる。 しかし列も連動して十字に色を変えようとすると、これまでは JavaScript でやるしかなかった。 しかし has が使えるようになった今なら、 css だけで実装できるのではないか。

で、やってみたのがこれ。

c1 c2 c3 c4 c5
r1 11 12 13 14 15
r2 21 22 23 24 25
r3 31 32 33 34 35
r4 41 42 43 44 45
r5 51 52 53 54 55

html

<table class="smpl1"> <colgroup> <col /> <col /> <col /> <col /> <col /> <col /> </colgroup> <thead> <tr> <td></td> <th>c1</th> <th>c2</th> <th>c3</th> <th>c4</th> <th>c5</th> </tr> </thead> <tbody> <tr> <th>r1</th> <td>11</td> <td>12</td> <td>13</td> <td>14</td> <td>15</td> </tr> 〜中略〜 <tr> <th>r5</th> <td>51</td> <td>52</td> <td>53</td> <td>54</td> <td>55</td> </tr> </tbody> </table>

css

table.smpl1 { tbody tr:hover { background-color: yellow; } &:has( :is( th, td ):nth-child( 2 ):hover ) col:nth-child( 2 ) , &:has( :is( th, td ):nth-child( 3 ):hover ) col:nth-child( 3 ) , &:has( :is( th, td ):nth-child( 4 ):hover ) col:nth-child( 4 ) , &:has( :is( th, td ):nth-child( 5 ):hover ) col:nth-child( 5 ) , &:has( :is( th, td ):nth-child( 6 ):hover ) col:nth-child( 6 ) { background-color: yellow; } }

行の色指定については、特に言うことは無い。

列は、そもそもの話から。 まず、以下が効かない。

col:hover { background-color: yellow; }

まあ DOM 的には th や td は col の子要素ではないので、イベントが伝播しないって仕様も理解はできるのだが。

で、思いついたのが、 has を使って hover を間接的に効かすこと。

指定の列の th または td にマウスカーソルが乗っているテーブルの、同じ列の col に背景色を指定する。

思いついたとき、なんかいけそうな気はしたが、確信は持てなかったんだよな。 でもやってみたら出来た。

この方法の利点は、色々応用が効くこと。 今回は簡単な例として col と nth-child を使ったが、 col は th や td でも良いし、 nth-child は列毎につけたクラス名でも良いだろう。

欠点は、 hover を拾う位置とスタイルを適用する列とを対応させるために、列毎に定義が必要になること。 この例のように5列程度なら根性で何とかなるが、この辺りが限界だろうとも思う。 これ以上の列数に適用するなら、スタイル定義を自動生成した方がいいだろう。

そしていつもの感想だが、便利になったよな。 今回は has に併せて is も使った。 あと、スタイルの入れ子定義も。 これが10年前にあったらなぁ… と思いながら。