CSSのコンテナクエリと:has()擬似クラスを使用すると、こんなことができるようになる
Post on:2022年4月12日
CSSのコンテナクエリと:has()
疑似クラスを使用するとこんなことができる、というのをGoogleデベロッパーのUna氏が公開していたので、紹介します。
簡単に説明すると、:has()
疑似クラスは引数の要素を含んでいるかをCSSで判別できます。.card:has(.visual)
でカード内に画像(.visual
)が含まれている場合のスタイル、.card:not(:has(.visual))
で含まれていない場合のスタイルを定義できます。
下記は、カードに画像が含まれている場合は見出しのfont-size
を小さく、含まれていない場合は大きくしています。
先日リリースされたSafari 15.4で、:has()
疑似クラスがサポートされました。Chromeは次期101のflagsで使用できる予定(Canaryはすでに使用できます)で、すべてのブラウザにサポートされる日が近づいてきました。また、コンテナクエリはすでにChrome 93のflagsで使用でき、SafariのTPにも実装され、こちらもサポートされる日が近づいてきました。
Safari 15.4は、macOS Montereyだと自動アップデートされますが、それ以外だと自動アップデートされません。ソフトウェアアップデートのmacOS Montereyから「ほかにもアップデートがあります」の詳しい情報からアップデートできます。
まず、CSSのコンテナクエリと:has()
疑似クラスを簡単に説明します。
- コンテナクエリとは
- コンテナクエリは
@media
クエリに似ていますが、ビューポートではなく親コンテナのサイズに対してスタイルを適用できます。 :has()
疑似クラスとは:has()
は指定した要素を含んでいる場合にスタイルを適用できます。
さらに詳しくは、下記をご覧ください。
:has()
疑似クラスは2022年4月現在サポートされているブラウザはSafariのみですが、ポリフィルを使用すればすべてのモダンブラウザで使用できます。
- CSSの新機能コンテナクエリのポリフィルがこれほど使いやすく、Googleから提供されたことは素晴らしい
- Container Query Polyfill
- CSS Has Pseudo(IEもサポート)
デモがどのように機能するのか、見てましょう。
2つのカードがあり、1つ目は画像あり、2つ目は画像なし、です。画像がある場合にはfont-size
が小さくなり、ない場合にはfont-size
が大きなくります。
コンテナが400px以上の場合
さらに、コンテナクエリを使用してコンテナの幅が400px未満になると、画像がある場合には積み重なり、画像がない場合には積み重ねはなしです。
コンテナが400px未満の場合
CSSは、下記の通りです。
画像のあり・なしは.card:has(.visual)
, .card:not(:has(.visual))
で記述されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.container { container: inline-size; } .card { display: grid; } .card:has(.visual) { grid-template-columns: 1fr 1fr; } .card:has(.visual) h1 { font-size: 2rem; } .card:not(:has(.visual)) h1 { font-size: 4rem; } |
コンテナクエリと:has()
擬似クラスは、Chrome Canaryの最新版でflagsをオンにすると、動作します。
アドレスバーにchrome://flags/
を入力して、上記の2つを有効にします。
実際のデモは、下記でご覧ください。
Chrome Canary, Safari TPで動作します。
See the Pen
Simple CQ Demo with :has() by Una Kravets (@una)
on CodePen.
元ネタのツイートは、下記より。
:has() + container queries = the component-based logical styling we've always dreamed of 😍
In this demo:
🖼 If the card has an image: make the font smaller & at < 400px wide, stack it
✨ If no image: bigger font, no stackinghttps://t.co/UJuXCXUrvV⚠️ Need flags on in Canary pic.twitter.com/ThhPLHDWak
— una.css 👩🏻💻🇺🇦 (@Una) April 2, 2022
sponsors