これは覚えておきたい! CSSの:has()疑似クラスを使うと、こんな面倒な実装も簡単なCSSだけできる
Post on:2024年2月14日
CSSの:has()
疑似クラスは去年末にFirefoxでサポートされ、これですべてのブラウザにサポートされました。2024年は、:has()
疑似クラスを使用する機会が増えますね。
CSSの:has()
疑似クラスは指定した要素がある場合にのみスタイルを適用できる、if
文のような非常に便利なCSSの機能です。この:has()
疑似クラスの基本的な使い方とシンプルだけどクールな使い方を紹介します。
↔️ Sideway selection in CSS with :has()
by Francesco Vetere
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
:has()疑似クラスのシンプルでクールな使い方
みなさん、こんにちわ!👋
この記事では、最近すべてのブラウザにサポートされた:has()
疑似クラスのシンプルでクールな使い方を解説したいと思います。
まずは、デモページをご覧ください!
See the Pen
Emoji rections dock -- sideway selections with :has() by coliss (@coliss)
on CodePen.
それぞれの絵文字にカーソルを置くと、その絵文字がスムーズにポップアップするだけでなく、その絵文字の左右の兄弟も影響を受けて、とても心地よいエフェクトを生み出すことに気がつくと思います。
このエフェクトは、現在ではすべての主要なブラウザにサポートされた:has()
疑似クラスのおかげです。
2023年12月にリリースされたFirefox 121でサポートされ、これで:has()疑似クラスがすべてのブラウザにサポートされました。詳しくは、CSSの:has()疑似クラスがすべてのブラウザにサポートされました、:has()疑似クラスの便利な使い方のまとめをご覧ください。
実装の解説
:has()
は機能的な疑似クラスで、ある要素をその子孫や後続の要素に基づいてスタイルを設定することができます。
:has()
を使用すると、基本的にターゲットになる要素にスタイルを設定することができます。これは:hover
のような他の疑似クラスと似ており、a:hover
はa
要素がホバーされた状態にスタイルすることを目的とされています。- ただし、
:has()
は括弧の中に相対セレクタのリストを設定できるという点で、:is()
,where()
,:not()
に似ています。これにより、:has()
はターゲットとなる要素を設定できるため、非常に強力なセレクタと言えます。
まずは、:has()
疑似クラスの簡単な使用例を見てましょう。
子要素として<img>
を含むすべての<article>
要素をターゲットにしたい場合、:has()
を使用すると非常に簡単な記述でできます。
1 2 3 |
article:has(img) { /* ... */ } |
この使用例は、もっとも簡単なものの一つです。:has()
疑似クラスは基本的に親セレクタと機能し、Webプラットフォームに欠けていたもので、デベロッパーが何年にもわたり強く求めていた機能です。
それだけではありません!
:has()
疑似クラスは相対セレクタのリストを引数として受け取るので、親要素以外にも多くの要素をターゲットにできます。さまざまなセレクタを使用することで、DOMツリーを上がる↑だけでなく、横方向↔️の選択もできるようになりました。
たとえば、article:has(+ article)
は、直接の兄弟として別の<article>
要素を持つ<article>
要素をターゲットにします。簡単に見えるかもしれませんが、これは:has()
がなければ不可能で、それ以前はJavaScriptが必要でした。
私がこの記事で紹介したデモは、まさにこのアイデアを利用しています。現在ホバーされている要素だけでなく、その兄弟(左右)の要素にもスタイル(拡大縮小と変換)を適用したいと考えました。
:has()
疑似クラスを使用すると、これを簡単に実現できます。
1 2 3 4 5 6 7 8 9 10 11 |
.dock li:hover { /* ホバーされた要素を拡大縮小・変換 */ } .dock li:hover + li { /* 次の要素を拡大縮小・変換 */ } .dock li:has(+ li:hover) { /* 前の要素を拡大縮小・変換 */ } |
もちろん、完全なコードはもう少し複雑ですが、主なアイデアはこのシンプルなCSSに基づいています。その要素自身とその次の兄弟要素だけでなく、前の兄弟要素もターゲットにする方法を使用できるようになったことで、まったく新しい世界が開かれます。
最後に、:has()
疑似クラスを使用して、構築した素晴らしいものがあれば教えてください 😉
sponsors