1. このページの目的
CSS の Container queries と :has()
を試します。
@container and :has(): two powerful new responsive APIs landing in Chromium 105 - Chrome Developers という記事の中で、この2つは a match made in responsive heaven であると紹介されています。a match made in heaven というのは「相性がよい二人」とか「最高の組み合わせ」といった意味で、この中の heaven を responsive heaven に変えることによって、「レスポンシブに関して最高の組み合わせである」といった意味を表しているようです。
2. デモ
2-1. Container queries
<div class="card-container">
<div class="card">
<p>foo</p>
<p>bar</p>
</div>
</div>
.card-container {
container-type: inline-size;
}
.card {
display: grid;
grid-template-columns: 1fr 1fr;
}
@container (width <= 550px) {
.card {
grid-template-columns: 1fr;
}
}
- コンテナとする要素に
container-type
を指定します。 @container
で、コンテナ要素に対する条件を指定し、その条件に合致した場合に適用するスタイルを、その中に記述します。- ここでは、
@container
の部分に、そのサイズの対象となるコンテナ要素を指定していません。この場合、そのセレクタに合致する要素から見て最も近いコンテナのサイズが判断の対象となります。一方、container-name
プロパティでコンテナに名前を付けておけば、@container
で指定することができます。 container-name
プロパティの Syntax は以下です。container: <container-name> / <container-type>;
- ここでは、
- 幅の条件指定には、Media Queries - Level4 で利用が可能になった不等号を使っています。
foo
bar
- コンテナに指定した要素の幅(viewport の幅でないのがポイントです)が 550px より大きいと 2カラム、それ以下だと 1カラムになります。
- このコンテナを表示できる領域の最大幅がどれくらいだろうと、あくまでこのコンテナの幅に対して場合わけできるので便利です。あって当然の機能でしょう。今まで viewport の幅でしか場合分けできなかったのがありえない状況でした。
2-2. :has()
<p><span>span要素</span> を含む p要素の背景色は黄色になります。</p>
<p>こちらは、span要素を含まない p要素です。</p>
p {
background-color: #ccc;
border: 1px solid black;
padding: .5em;
}
span {
border: 1px solid black;
}
p:has(span) {
background-color: yellow;
}
span要素 を含む p要素の背景色は黄色になります。
こちらは、span要素を含まない p要素です。
2-3. Container queries と :has() を組み合わせて使う
@container and :has(): two powerful new responsive APIs landing in Chromium 105 - Chrome Developers
を参照して下さい。2-4. jQueryの has() と :has() をどちらも使った場合を実験する
.has() | jQuery API Documentation Example のコードを利用している。
<div class="demo demo2-4">
<ul><li>Does the UL contain an LI?</li></ul>
</div>
.demo2-4 ul:has(li) {
color: blue;
}
let $ = jQuery;
$( ".demo2-4 ul" ).append( "<li>" +
( $( ".demo2-4 ul" ).has( "li:contains('Does')" ).length ? "Yes" : "No" ) + "</li>" );
$( ".demo2-4 ul" ).has( "li" ).addClass( "full" );
- Does the UL contain an LI?
- この例だと問題なく動作する。
- jQueryの拡張セレクタを `:has()` 内で使っていたら問題になるらしいが、そんな使い方をするものなのか?が分からない。
3. 参考
- @container and :has(): two powerful new responsive APIs landing in Chromium 105 - Chrome Developers
- CSS Container Queries - CSS: Cascading Style Sheets | MDN
- container - CSS: Cascading Style Sheets | MDN
- container-name - CSS: Cascading Style Sheets | MDN
- Media Queries Level 4
- [selectors] The forgiving nature of :has breaks jQuery when used with a complex :has selector · Issue #7676 · w3c/csswg-drafts · GitHub