CSSの :has()
擬似クラスは、特定の要素が特定の子要素や内容を持っているかどうかを判断し、その親要素にスタイルを適用できるとても便利な機能です。今回は、この擬似クラスについてまとめていきたいと思います。
目次 非表示
:has()
は「親要素が特定の子要素を持っている場合」に適用できる擬似クラスです。従来のCSSでは、親要素を子要素の状態に応じて変更することはできませんでしたが、:has()
を使用することで可能になります。
div:has(img) {
border: 2px solid blue;
}
上記の例では、<div>
の中に <img>
要素が含まれている場合、その div
に青い枠線が適用されます。
特定の要素の中にh2
要素が含まれている場合は、背景色を変更してみます。
See the Pen Untitled by tones (@tonescodedesign) on CodePen.
<div class="columns">
<div class=col>
<h2>h2見出し</h2>
<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
</div>
<div class="col">
<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
</div>
</div>
.columns {
display: flex;
gap: 30px;
}
.col {
padding: 30px;
color: #fff;
background-color: #94b4ce;
}
.col:has(h2) {
background-color: #82a694;
}
上記は、h2
がある場合は「#82a694;」になるように設定しています。
次は、h2
の「margin-bottom」の数値を後に続く要素によって変更してみます。
例えば、h2
の基本となるmargin-bottomを30pxとします。ただし、h2
のすぐ後にh3
要素が続く場合はh2
のmargin-bottomを違う数値に変更したい、という場合は以下のように設定ができます。
See the Pen :has() by tones (@tonescodedesign) on CodePen.
h2 {
margin: 0 0 30px;
}
h2:has(+ h3) {
margin-bottom: 15px; /* h2の後にh3が続く場合は15px */
}
h3 {
margin: 0 0 15px;
}
/* spanタグを含むh2に対して */
h2:has(span) { ... }
/* figcaptionがあるfigure要素に対して */
figure:has(> figcaption) { ... }
/* figcaptionがないfigureに続くp要素に対して */
figure:not(:has(figcaption)) + p { ... }
/* 直下にa要素がない.containerに対して */
.container:not(:has(> a)) { ... }
/* 子要素の数が3つ以上の.containerに対して */
.container:has(> .container__item:nth-child(3)) { ... }
/* 子要素の数が偶数の.containerに対して */
.container:has(> .container__item:last-of-type:nth-of-type(even)) { ... }
このように:has()
を活用することで、より柔軟なCSS設計が可能になります。
:has()
は親要素に適用されるため、影響範囲が広くなりやすいです。パフォーマンスを考慮し、できるだけ特定の要素に対して適用するようにしましょう。