【CSS】特定の子要素(ID、class、タグ)を持たない親要素の指定方法

この記事は約5分で読めます。

元のCSSの指定を消せなかったり、wordpressでサイトを構築してる時に、こうゆう複雑な指示ってするよね。
CSSが複雑化するからあまりやりたくはないけど仕方ない時あるからそんな時のためにメモメモ。

まずは、指定方法ね!

/* 例:子要素にpタグを持たない親要素を選択 */
.parent:not(:has(p)) {
  /* スタイル */
}

/* 例:子要素にclass="target"を持たない親要素を選択 */
.parent:not(:has(.target)) {
  /* スタイル */
}

/* 例:子要素にid="target"またはclass="target"を持たない親要素を選択 */
.parent:not(:has(#target), :has(.target)) {
  /* スタイル */
}

解説

CSSで親要素が特定の子要素(ID、class、タグ)を持たない場合に、その親要素を指定するには、:has()疑似クラスと:not()疑似クラスを組み合わせます。

:has()疑似クラス

CSSに関する調査である「State of CSS 2024」によると、:has擬似クラスは、2024年の1年間で2番目に多く使用されたCSS機能。
みんな求めてた機能なんだ。
:has()疑似クラスは、指定されたセレクタにマッチする子要素を持つ要素を選択します。つまり、:has(p)は、子要素に<p>タグを持つ要素を選択します。

:not()疑似クラス

:not()疑似クラスは、指定されたセレクタにマッチしない要素を選択します。つまり、:not(p)は、<p>タグではない要素を選択します。

:not()疑似クラスは、セレクタリスト(カンマで区切られたセレクタのリスト)を受け付けることができます。セレクタリスト内のいずれかのセレクタにマッチする場合、要素は:not()疑似クラスにマッチしません。

/* 例:pタグまたはdivタグではない要素を選択 */
:not(p, div) {
  /* スタイル */
}

:not()疑似クラスは、別の:not()疑似クラスを引数として受け取ることはできません。

/* 無効なCSS */
:not(:not(p)) {
  /* スタイル */
}

:not()疑似クラスのセレクタリストに擬似要素を含めることはできません。

/* 無効なCSS */
:not(::before) {
  /* スタイル */
}

:not()疑似クラスは、:validや:invalidなどの一部の擬似クラスと組み合わせることができます。

/* 例:有効な入力フィールドではない要素を選択 */
:not(:valid) {
  /* スタイル */
}

:has()と:not()の組み合わせ

:has()と:not()を組み合わせることで、「特定の子要素を持たない親要素」を選択できます。

/* 例:子要素にpタグを持たない親要素を選択 */
.parent:not(:has(p)) {
  /* スタイル */
}

このCSSは、.parentクラスを持つ要素のうち、子要素に<p>タグを持たない要素を選択します。

具体的な例

以下のHTML構造を例に、具体的なCSSの記述方法を見ていきましょう。

<div class="parent has-p">
  <p>段落</p>
</div>

<div class="parent has-div">
  <div>div要素</div>
</div>

<div class="parent no-children">
</div>

1. pタグを持たない親要素にスタイルを適用する

.parent:not(:has(p)) {
  background-color: lightgray;
}

このCSSは、.parentクラスを持つ要素のうち、子要素に<p>タグを持たない要素の背景色を薄い灰色にします。結果として、「div要素を持つ親要素」と「子要素を持たない親要素」の背景色が薄い灰色になります。

2. class = “target”を持たない親要素にスタイルを適用する

.parent:not(:has(.target)) {
  border: 2px solid red;
}

このCSSは、.parentクラスを持つ要素のうち、子要素にclass=”target”を持つ要素がない要素のボーダーを赤色の2pxの線にします。

3. id=”target”またはclass=”target”を持たない親要素にスタイルを適用する

.parent:not(:has(#target), :has(.target)) {
  font-weight: bold;
}

このCSSは、.parentクラスを持つ要素のうち、子要素にid=”target”またはclass=”target”を持つ要素がない要素の文字を太字にします。

応用例

:has()と:not()を組み合わせることで、より複雑な条件で親要素を選択できます。

/* 例:子要素にpタグがなく、かつclass="special"を持たない親要素を選択 */
.parent:not(:has(p), :has(.special)) {
  /* スタイル */
}

注意点

  • :has()疑似クラスは、比較的新しい機能です。古いブラウザでは動作しない場合があります。
    詳しくはCan I useで確認してください。
  • :has()疑似クラスは、パフォーマンスに影響を与える可能性があります。
    複雑な条件で使用する場合は、注意が必要です。

まとめ

:has()と:not()を組み合わせることで、CSSでより柔軟で複雑なスタイリングが可能になります。
ちょっと複雑で、別の人がこのコードを書いていざ自分が回収する時になったらわかりづらいかもだけど、ある程度理解すれば色々便利に使えそうだよね。
ぜひ活用してみてください。

コメント

タイトルとURLをコピーしました