【CSS】疑似クラスセレクター/:has()

特定の要素を選択するための「CSSセレクター」には、要素の状態や位置に基づいてスタイルを適用できる疑似クラスセレクター(:hoverなど)があります。本記事では、その疑似クラスセレクターの中でも比較的新しく実装された:has()について解説します。

目次

そもそも疑似クラスセレクターとは?

疑似クラスセレクター(pseudo-class selector)とは、特定の条件においてスタイルを適用できるCSSの機能。「疑似」とは、その要素自体の状態や位置に基づいてスタイルを適用できるため、実際のHTMLには存在しない状態(例えば、マウスホバーした状態など)でもスタイルを指定できます。

これによって、ユーザーの操作(:hover:focus)や要素の状態(:checked:disabled)などに基づいた、インタラクティブな(動的な)デザインが可能になります。

:has() 疑似クラスセレクターとは?

CSSの :has() 疑似クラスセレクターは、特定の要素が子要素、子孫要素、または任意の後続要素を持つ場合にスタイルを適用したい場面で使用されます。「親要素に特定の子要素があるかどうか」を条件にしてスタイルを適用するなど、CSSに条件式を適用したい場合に非常に便利です。

2024年6月、一部の古いブラウザを除き、ほとんどのブラウザでサポートされています。

  • Google Chrome
  • Mozilla Firefox
  • Microsoft Edge
  • Safari
  • Internet Explorer

基本1:特定の要素が含まれている場合にスタイルを適用

以下は、p要素を含むdivに対してスタイルを適用する例です↓

/* div が p 要素を含んでいれば、その div に背景色を適用 */
div:has(p) {
  background-color: skyblue;
}
実装例

HTMLコード

<div>
  <p>p要素がある場合、親のdivの背景色は水色になります。</p>
</div>

<div>
  p要素がないので、スタイルは適用されません。
</div>

ブラウザ表示

p要素がある場合、親のdivの背景色は水色になります。

p要素がないので、スタイルは適用されません。

基本2:特定のクラスを持つ要素が含まれている場合にスタイルを適用

「特定のクラスを持つ要素が含まれている」というような条件に対してスタイルを適用することもできます。
以下は、divclass="highlight" を持つ要素を含む場合にスタイルを適用する例です↓

/* div が .highlight クラスを持つ要素を含んでいれば、その div に赤い枠線を付ける */
div:has(.highlight) {
  border: 2px solid red;
}
実装例

HTMLコード

<div>
  <span class="highlight">highlightクラスを持つ要素がある場合、親のdivは赤い枠線が付きます。</span>
</div>

<div>
  highlightクラスを持つ要素がないので、スタイルは適用されません。
</div>

ブラウザ表示

highlightクラスを持つ要素がある場合、親のdivは赤い枠線が付きます。
highlightクラスを持つ要素がないので、スタイルは適用されません。

基本3:特定の子要素が特定のクラスを持つ場合にスタイルを適用

より複雑な子要素を条件にしてスタイルを適用することもできます。
以下は、ul が特定の li 要素を持っている場合にスタイルを適用する例です。

/* ul が .square クラスを持つ li 要素を含んでいれば、その ul のリストスタイルを変更 */
ul:has(li.square) {
  list-style-type: square;
}
実装例

HTMLコード

<ul>
  <li>通常のリスト項目</li>
  <li class="square">特別なリスト項目</li>
</ul>

<ul>
  <li>通常のリスト項目</li>
  <li>通常のリスト項目</li>
</ul>

ブラウザ表示

  • 通常のリスト項目
  • 特別なリスト項目
  • 通常のリスト項目
  • 通常のリスト項目

:has() 疑似クラスセレクターの応用的な使い方

:has() セレクターは、特定の条件に基づいた高度なスタイリングが可能です。中・上級者向けの使い方をいくつかご紹介します。

応用1:フォームが特定の入力フィールドを持つ場合にスタイルを適用

フォームが特定の入力フィールドを含んでいる場合に、そのフォーム全体にスタイルを適用する例です。

/* フォームが `.error` クラスを持つ入力フィールドを含む場合 */
form:has(input.error) {
  border: 2px solid red;
}

/* フォームがチェックボックスを含む場合 */
form:has(input[type="checkbox"]) {
  background-color: limegreen;
}
実装例

HTMLコード

<form>
  <label for="input1">通常のインプット要素</label>
  <input type="text" id="input1">
</form>

<form>
  <label for="input2">エラーのインプット要素</label>
  <input type="text" id="input2" class="error">
</form>

<form>
  <label for="input3">チェックボックス</label>
  <input type="checkbox" id="input3">
</form>

ブラウザ表示

応用2:インタラクティブなナビゲーションメニューを作る

ナビゲーションメニューで、特定のページが選択されている場合に親メニュー項目のスタイルを変更する例です。

/* ナビゲーションメニューで `.active` クラスを持つ項目を含む場合 */
nav ul:has(li.active) {
  font-weight: bold;
}

/* `.dropdown` クラスを持つリスト項目がホバーされている場合 */
nav ul li.dropdown:has(ul:hover) {
  background-color: #eee;
}
実装例

HTMLコード

<nav>
  <ul>
    <li>Passive</li>
  </ul>
</nav>

<nav>
  <ul>
    <li class="active">Active</li>
  </ul>
</nav>
<nav>
  <ul>
    <li>Home</li>
    <li>About</li>
    <li class="dropdown">
      Services
      <ul>
        <li>Web Design</li>
        <li>SEO</li>
        <li>Marketing</li>
      </ul>
    </li>
    <li>Contact</li>
  </ul>
</nav>

ブラウザ表示

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次