皆さんこんにちは、アンドレです。
コーダーの皆さん、:has()、使ってますか?
Firefoxのサポートが遅かった(2023/12/19のVer.121から)ため、昨年の特に序盤などはある程度様子を見ながら使っていたのですが、さすがにもう大丈夫だろうということで、記事にすべく筆を執りました。
さて、一体:has()の何がすごいのか、についてですが、端的に言えば、
今まで(CSSだけでは)できなかったことができる
のです。
まず、兄弟の関係において、
例えば、特定の要素(Aとします)を前に持つ要素(Bとします)であれば、次兄弟結合子を用いれば
A + B {
という形でスタイルを制御することができましたが、その逆の、特定の要素(B)を後に持つ要素(A)を指定する術はありませんでした。
それが:has()を使えば、
A:has(+ B) {
という形で指定でき、さらにBに特定の要素が含まれているか、なども条件とすることが可能となります。
例えば後続のBにCが含まれている場合、としたかったら、
A:has(+ B C) {
とすればOKです。
また、親子の関係においては、
特定の親を持つか(=コンテキスト)による子要素のスタイル制御はできましたが、その逆の、特定の子要素を持つ親要素に対してスタイルを適用することはできませんでした。
ですので、例えばフォーム内にエラー文言(.errorとします)があったらフォームの背景色を赤色にしたい、という場合は、JSで.errorの有無を調べ、あったらフォームに.has_errorのようなclassを追加(して背景色を変更)したりしていました。
それが:has()を使えば、
form:has(.error) {
と記述するだけでOKなのです。便利でしょう?
ここからは、私がこれは便利だ! と感じたケースを2つほどご紹介したいと思います。
スライド(カルーセル)の項目が1つしかないときに進める/戻るボタンを非表示
See the Pen スライド(カルーセル)の項目が1つしかないときに進める/戻るボタンを非表示のサンプル by Takamasa Okada (@NP-okada) on CodePen.
スライド項目(.splide__slide)が1つだけ(:only-child)のスライド(.splide)のナビゲーション(.splide__arrows)を非表示に、という指定の仕方です。
メニューボタンの状態変更だけでメニューとオーバーレイも制御する
See the Pen メニューボタンの状態変更だけでメニューとオーバーレイも制御するサンプル by Takamasa Okada (@NP-okada) on CodePen.
メニューボタンの状態(aria-expanded)の変更だけで、右からメニューをスライド表示&オーバーレイの表示をさせています。
:has(.menuBtn[aria-expanded=true])
という形で直接関係のない.menuBtnの状態を拾ってきているのがミソです。
:has()のすごさ、伝わりましたでしょうか?
ぜひ活用して、シンプルかつスマートなコーディングの実現に役立てていただければと思います。
それでは、また。