何で困ったか
タイトルの通りですが、子要素のhoverを検知して、親要素のStyleを変更したかった。
意外とハマってしまったので、やり方をメモしておきたいと思います。
前提条件
React, scssを使用
結論
:has()
を使って親要素のStyleを変更するのが良さそう。
tsx sample
<div className={styles.parent}>
<div className={styles.blos1}>
<button className={styles.child1}>hoge</button>
</div>
<div className={styles.blos2}>
<button className={styles.child2}>fuga</button>
</div>
</div>
scss sample
.parent {
&:has(.child1:hover, .child2:hover) {
backgroundColor: lightgreen;
}
.blos1 {
&:has(.child1:hover) {
backgroundColor: lightblue;
}
&:has(.child2:hover) {
backgroundColor: darkred;
}
}
.blos2 {
&:has(.child1:hover) {
backgroundColor: darkred;
}
&:has(.child2:hover) {
backgroundColor: lightblue;
}
}
この様に記述すると、
それぞれのbuttonにホバーさせると、それぞれの親要素に背景色を着けることができる。
コードの説明
.parent {
&:has(.child1:hover, .child2:hover) {
backgroundColor: lightgreen;
}
.parent
にスタイルを当てる時の条件を記述。
:has()
の引数部分に該当する条件を書く。
この場合、.child1のbuttonにhoverが当たった時か、.child2のbuttonにhoverが当たった時に、ブロック内のstyleが適用される。
なので、.button1, .button2のクラスがついた要素のどちらかにhoverが入った時、
backgroundColorがlightgreenになる。
これと同じように以下のコードを見ると、
.blos1 {
&:has(.child1:hover) {
backgroundColor: lightblue;
}
&:has(.child2:hover) {
backgroundColor: darkred;
}
}
となっているので、
blos1の要素は、child1のボタンにhoverが当たると、lightblueの背景色が着き、child2のボタンにhoverが当たると、darkredの背景色がつくような記述になる。
(.blos2も基本同様の動きで背景色が逆になっている)
まとめ
子要素の条件をもとに親要素のstyleを変更したい場合は、:has()を使ってみるとすっきり記述できると思います。
.tsx側でclassを当てる制御を行う方法でも良いですがscssで記述できる部分はサクッとscssで当てられるようになりたいですね。
今回もいい勉強になりました。