最近のCSSには階層をさかのぼってクラスを指定したり、特定のクラスを持っている場合に効かせたいなど、本来JSで行うような条件分岐的な処理が可能になってきた。
普段は使うことは少ないが、クラスを追加したり、JSを使うことが好ましくない場合に使用することが稀にある。
自分も一度そのようなケースに遭遇して使用したので、今後のメモとして残しておく。
完成系は下記のようなイメージだ。
See the Pen CSSでの条件分岐 by Tomizawa (@masaya_coding) on CodePen.
Table of Contents
HTML
HTMLはひな形としてbodyにactyiveクラスが付いているという想定で行う。
またその下の階層に祖先要素、親要素、子要素、孫要素がそれぞれ配置されている。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script src="https://t-creative-works.com/js/jquery-3.5.0.min.js"></script>
</head>
<body class="active">
<div class="grandparents">
<div class="parents parents_01">
<p>親要素のPタグ(1)</p>
<div class="child child_01">
<p>子要素のPタグ(1)</p>
<div class="grandchild_01">
<p>孫要素のPタグ(1)</p>
</div>
</div>
</div>
<div class="parents parents_02">
<p>親要素のPタグ(2)</p>
<div class="child child_02">
<p>子要素のPタグ(2)</p>
<div class="grandchild_02">
<p>孫要素のPタグ(2)</p>
</div>
</div>
</div>
<div class="parents parents_03">
<p>親要素のPタグ(3)</p>
<div class="child child_03">
<p>子要素のPタグ(3)</p>
<div class="grandchild_03">
<p>孫要素のPタグ(3)</p>
</div>
</div>
</div>
<div class="parents parents_04">
<p>親要素のPタグ(4)</p>
<div class="child child_04">
<p>子要素のPタグ(4)</p>
<div class="grandchild_04">
<p>孫要素のPタグ(4)</p>
</div>
</div>
</div>
</div>
</body>
</html>
CSS
先ほどのHTML要素を使い、「○○要素がある場合は××要素にCSSを~~」という処理を書いていく。
/*bodyがkingというクラスを持っていたら、親要素のhtmlタグにcss付与*/
html:has(> body.active) {
overflow: hidden;
}
/*もし.childが.child_01というクラスをもっていたら.parents_01の色変更*/
.parents_01:has(> .child.child_01) {
color: red;
}
/*parents_03がchild_03を持っているときの、.parents_04への処理*/
.parents_03:has(> .child_03) + .parents_04 {
color: red;
}
/*もし.parents_01が同階層にあった場合、.parents_02の子要素.child以下の色変更*/
.parents_01 ~ .parents_02 .child {
color: aqua;
}
順を追って説明していく。
①hasで特定のクラスがある時に処理
コメントアウト部分にも書いてあるが、「:has(>~」というのは、その子要素に特定のクラスが付いている場合という処理が行われる。
これはモーダルやポップアップなどを出すときに背景やz-indexを操作する時に使うことが多い印象だ。
※1~9行目までこの処理
②「has」と「+」で○○に子要素△△がある場合は××にCSSを充てる
自分は今まで一度だけ「+」を使ったCSSを書いたことがある程度で、使用頻度は少な目だ。
今回の例でいうと、「.parents_03:has(> .child_03) + .parents_04{~~~}」は下記のような意味になる。
「.parents_03」が子要素に「.child_03」を持っている時、「.parents_04」にCSSを充てる。
つまり.parents_04にのみCSSが充たるのだが、.parents_03が.child_03を持ってなければならないという条件分岐のような形となっている。
③「~」で○○と××が同階層にある場合、××にCSSを充てる
「~」は②と非常に似ているが、今度は同階層に○○がある場合に処理を行うといったもになる。
例文の「.parents_01 ~ .parents_02 .child{~~~}」は下記のような意味となる。
もし「.parents_01」が「.parents_02」と同階層にあった場合、「.parents_02」の子要素「.child」にCSSを充てる。
こちらも使用頻度は極めて低いが、使わざるを得ない場合もあるので抑えておきたい。