【CSS】疑似クラス:has()について

どうも、くまだです。

わりと最近使えるようになったCSSの疑似クラス:has()についてのあれこれ。

疑似クラス:has()

例えば以下のように書くと「子要素にpタグを持つelementのみ、elementの背景色を変更するスタイル」を適用できます。

<div class="element">
   <span>スパンタグ</span>
</div>

<div class="element">
   <p>pタグ</p>
</div>
.element:has(p) {
background-color: red;
}

/*見た目調整用*/
.element+.element {
  margin-top: 16px;
}

以下のように、element:has(>p)と指定すれば「elementの直下にpタグがある場合、elementの背景色を変える」ことができます。

<div class="element">
  <span>スパンタグ</span>
  <div>
     <p>pタグ</p>
  </div>
</div>

<div class="element">
    <p>pタグ</p>
</div>
.element:has(>p) {
  background-color: red;
}

これまでは、特定の子要素がある場合の親要素のスタイルを変更することができませんでした。

親→子の場合で、特定の親要素の中の子要素のスタイルは変えることはできましたが、その逆はできませんでした(特定の子要素を持つ親、みたいな)。:has()を使えば、特定の子要素にマッチした場合の親要素のスタイルを変えることができるようになるので、子→親のスタイルを変更できます。

他に例を挙げると、以下のように別タブリンクの指定で、別窓アイコンを付けている場合、

<div class="box">
  <a href="" class="elemntLink" target="_blank" rel="noopener noreferrer">
     <img src="dummy.png" alt="">
  </a>

  <a href="" class="elemntLink" target="_blank" rel="noopener noreferrer">
        テキストリンク
  </a>
</div>
.box {
  display: flex;
  flex-direction: column;
}

.elemntLink + .elemntLink {
  margin-top: 16px;
}
.elemntLink img {
  max-width: 200px;
}



.elemntLink {
  position: relative;
}


.elemntLink[target="_blank"] {
  display: inline-flex;
  align-items: center;
}

.elemntLink[target="_blank"]::after {
  content: "";
  background: url(./window.png) no-repeat center / contain;
  width: 20px;
  height: 20px;
  display: block;
  margin-left: 8px;

}


.elemntLink[target="_blank"]:has(img)::after {
  display: none;
}

aタグの中に画像があるとき、そのaタグから別窓アイコンを消す、みたいなこともできます。

.elemntLink[target="_blank"]:has(img)::after {
  display: none;
}

ちなみに、疑似要素に対して:has()は指定できないようです。

.elemnt:after:has(~~) {
  ~~
}

ここまで読んでくださりありがとうございました。

この記事を書いた人