これまでのcssは、先にある要素 → 後にある要素 の順番(親→子、兄→弟、隣)で詳細度を高めるしかありませんでした。
それを逆向きに指定できるようになったのがhasセレクタです。
chrome、safariではすでに対応済ですが、悲しきかなfirefoxが未サポートです(執筆時時点)。
近年、firefoxを非推奨ブラウザとするサービスが目につくようになりましたが、長年firefoxを愛用している自分としてはfirefox対応を待っていきたい所存です。
:hasセレクタの使用例
「逆向きに指定できる」では抽象的すぎるのでいくつか使用例を挙げておきます。
子要素の数にあわせてレイアウトを変更
:not()セレクタと:nth-child(n)セレクタを併用して、3以上の子要素があれば3カラム、未満なら2カラムを指定します。
子要素が親要素のスタイルをコントロールする好例だと思います。
#test{
columns:3; /* 通常3カラム */
}
#test:not(:has(:nth-child(3))){
columns:2; /* nth-child(3)がない場合は2カラム */
}
要素の有無でスタイル変更
サブタイトルがあればタイトル下の余白を小さくするようなケース。
.header h2{
margin-bottom:40px;
}
.header:has(.sub-title) h2{
margin-bottom:20px;
}
/*
<div class="header">
<h2>Title</h2>
<p class="sub-title">SubTitle</p>
</div>
*/
focusされた要素以外を指定
div:has(:focus) > :not(:focus){ /* :focusの子要素を持つ親の子要素のうち:focusではないもの */
opacity: 0.5
}
See the Pen :has() selector by Takashi Abe (@TakeshiAbe) on CodePen.
ブラウザのサポート状況
冒頭に述べた通り、firefoxは:hasセレクタをサポートしていません。
firefox以外の主要ブラウザは対応済ですが、chromeが対応したのは先月末の話であり、かなりの数のchromeユーザーは:hasセレクタ未対応のchromeを使用しています。
趣味以外の制作で使用するのはもう少し待った方が良いかもしれません。