コンテナクエリが利用可能に
デベロッパーから最も要望の多かった機能の一つが、ウェブブラウザで利用可能になりました。Chromium 105 と Safari 16 では、サイズベースのコンテナクエリを作成して、これらのブラウザでコンテナクエリの単位値を使用できるようになりました。サイズベースのコンテナクエリと cq
単位をより簡単に使用できるように、Chrome の Aurora チームは コンテナクエリ ポリフィルの更新に取り組んできました。これにより、より多くのブラウザとユースケースをサポートできるようになり、この強力な機能を安心してご利用いただけるようになりました。
コンテナクエリとは
コンテナ クエリは、親要素の特徴をターゲットにして子要素のスタイルを設定するスタイル設定ロジックを記述できる CSS 機能です。親のサイズをクエリすることで、真にコンポーネントベースのレスポンシブ デザインを作成できます。これは、ビューポートのサイズ情報のみを提供するメディアクエリなどよりも、はるかに詳細で有用な情報です。
コンテナクエリを使用すると、ページ内の場所に応じて表示が変わる再利用可能なコンポーネントを作成できます。これにより、ページやテンプレート全体で復元力と応答性が大幅に向上します。
コンテナクエリの使用
次のような HTML があるとします。
<!-- card parent -->
<div class=”card-parent”>
<div class=”card>
<!-- card contents -->
…
</div>
</div>
コンテナクエリを使用するには、まず、トラッキングする親要素にコンテナ設定を設定する必要があります。これを行うには、container-type
プロパティを設定するか、container
省略形を使用してコンテナタイプとコンテナ名を同時に設定します。
.card-parent {
/* query the inline-direction size of this parent */
container-type: inline-size;
}
これで、@container
ルールを使用して、最も近い親に基づいてスタイルを設定できるようになりました。上記の画像のようなデザインで、カードが 1 列から 2 列に移動する場合は、次のように記述します。
@container (min-width: 300px) {
.card {
/* styles to apply when the card container (.card-parent in this case) is >= 300px */
/* I.e. shift from 1-column to 2-column layout: */
grid-template-columns: 1fr 1fr;
}
}
より整然とした明確なコードにするために、親要素コンテナに名前を付けます。
.card-parent {
container-type: inline-size;
/* set name here, or write this in one line using the container shorthand */
container-name: card-container;
}
次に、前のコードを次のように書き換えます。
@container card-container (min-width: 300px) {
.card {
grid-template-columns: 1fr 1fr;
}
}
コンテナ クエリユニット
コンテナクエリをさらに便利なものにするには、コンテナベースの単位値も使用します。次の表に、コンテナ ユニットで使用できる値と、コンテナのサイズに対応する値を示します。
単位 | 相対 |
---|---|
cqw | クエリコンテナの幅の 1% |
cqh | クエリコンテナの高さの 1% |
cqi | クエリコンテナのインラインサイズの 1% |
cqb | クエリコンテナのブロックサイズの 1% |
cqmin | cqi または cqb の小さい値 |
cqmax | cqi または cqb の大きい値 |
コンテナベースの単位を使用する例として、レスポンシブ タイポグラフィがあります。ビューポートベースの単位(vh
、vb
、vw
、vi
など)を使用して、画面上の任意の要素のサイズを指定できます。
.card h2 {
font-size: 15cqi;
}
このコードは、フォントサイズをコンテナのインライン サイズの 15% にします。つまり、インライン サイズ(幅)が大きくなるとフォントサイズが大きくなり、小さくなると小さくなります。さらに、clamp()
関数を使用して、タイポグラフィに最小サイズと最大サイズの上限を設定し、コンテナサイズに基づいてレスポンシブにサイズを設定します。
.card h2 {
font-size: clamp(1.5rem, 15cqi, 3rem);
}
これで、ヘッダーが 3rem
より大きく、.5rem
より小さくなることはありませんが、その間のコンテナのインライン サイズの 15% が占有されるようになります。
このデモでは、これをさらに一歩進めて、2 列表示で表示されるため、より広いカードのサイズ範囲を小さくします。
コンテナクエリのポリフィル
コンテナクエリは非常に強力な機能であるため、プロジェクトに安心して組み込めるようにしたいと考えています。そのうえで、ブラウザのサポートが大きな役割を果たすことを認識しています。そのため、Google ではコンテナクエリのポリフィルの改善に取り組んできました。このポリフィルは、以下で一般的なサポートを提供します。
- Firefox 69 以降
- Chrome 79 以降
- Edge 79 以降
- Safari 13.4 以降
圧縮時のサイズは 9 KB 未満で、ResizeObserver と MutationObserver を使用して、安定したブラウザで現在使用可能な完全な @container クエリ構文をサポートしています。
- 離散クエリ(
width: 300px
とmin-width: 300px
)。 - 範囲クエリ(
200px < width < 400px
とwidth < 400px
)。 - プロパティとキーフレーム内のコンテナ相対長単位(
cqw
、cqh
、cqi
、cqb
、cqmin
、cqmax
)。
コンテナクエリのポリフィルを使用する
ポリフィルを使用するには、次のスクリプトタグをドキュメントのヘッダーに追加します。
<script type="module">
if (!("container" in document.documentElement.style)) {
import("https://unpkg.com/container-query-polyfill@^0.2.0");
}
</script>
サービスを使用して、User-Agent
に基づいて条件付きでポリフィルを配信するか、独自のオリジンで自己ホストすることもできます。
ユーザー エクスペリエンスを最適にするには、最初は折り返しの下にあるコンテンツにのみポリフィルを使用し、ポリフィルを表示する準備ができるまで、@supports
クエリを使用して一時的に読み込みインジケータに置き換えることをおすすめします。
@supports not (container-type: inline-size) {
.container,
footer {
display: none;
}
.loader {
display: flex;
}
}
十分な速度のネットワークとデバイス、またはコンテナクエリをネイティブにサポートしているデバイスの場合、この読み込みインジケーターは表示されません。
新しいポリフィル機能
更新されたポリフィルでは、以下がサポートされます。
- ネストされた
@container
ルール。 @supports
クエリと@media
クエリの下に@container
ルールをネストすること、およびその逆がサポートされています。@supports (container-type: inline-size)
などの条件付き CSS は、ポリフィルの読み込み後に渡されます。- CSS 構文の完全なサポート(構文的に有効な場所にコメントを配置しても問題は発生しません)。
- 縦書きモード(筆記モードを使用)。
- コンテナ相対単位(
cqw
、cqh
など)は、クエリ条件、プロパティ宣言、アニメーション キーフレーム内でサポートされています。rem
とem
はクエリ条件でサポートされています。 - 拡張コンテナクエリの構文:
<ph type="x-smartling-placeholder">
- </ph>
- 範囲の構文(例:
(200px < width < 400px)
)。 - 等式クエリ(例:
(width = 200px)
)。
- 範囲の構文(例:
::before
や::after
などの疑似要素。:is(...)
/:where(...)
のないブラウザは、オプションの回避策でサポートされています。orientation
とaspect-ratio
の特徴クエリ。- 機能に基づいてクエリを正しくフィルタリングしました(たとえば、
container: inline-size
に対するheight
のクエリは横書きモードでは正しく禁止されます)。 - DOM の変更(実行時に
<style>
要素と<link>
要素が削除されるなど)。
ポリフィルの制限事項と警告
コンテナクエリのポリフィルを使用している場合、注意すべき機能がいくつかあります。
- Shadow DOM はまだサポートされていません。
- コンテナの相対単位(例:
cqw
、cqh
)は、@media
クエリ条件ではサポートされていません。- Safari: コンテナ相対単位は、15.4 より前のアニメーション キーフレームではサポートされていません。
calc()
、min()
、max()
などの数学関数は、クエリ条件ではまだサポートされていません。- このポリフィルは、インラインの同一オリジンの CSS でのみ機能します。クロスオリジンのスタイルシートと iframe 内のスタイルシート(ポリフィルが手動で読み込まれる場合を除く)はサポートされていません。
layout
とstyle
の封じ込めには、基盤となるブラウザのサポートが必要です。 <ph type="x-smartling-placeholder">- </ph>
- Safari 15.4 以降
- Firefox では現時点ではスタイルの制限はサポートされていませんが、対応に向けて取り組んでいます。
警告
- FID と CLS に影響を与えないようにするため、ポリフィルは最初のレイアウトが同期的に読み込まれる場合でも、最初のレイアウトがいつ行われるかについては保証しません。ただし、LCP の不当な遅延を回避するためです。つまり、最初のペイントには使用しないでください。
ResizeObserver Loop Errors
を生成します。元のポリフィルでもこの処理が行われますが、ここで注意しておきましょう。これは、container-type: inline-size
のブロックサイズがクエリの評価後に変化する可能性が高いものの、ResizeObserver
にはブロックサイズの変更が重要でないことを示す方法がないためです。- このポリフィルをウェブ プラットフォーム テストでテストしたところ、70% の合格となりました。JavaScript API などの一部の機能はポリフィルされていないため、合格率を意図的に 70% に近づけています。
- 次のバージョンより前のブラウザの 2.23% には、
:where()
の回避策が必要です。 <ph type="x-smartling-placeholder">- </ph>
- サファリ 14
- Chromium 88
- エッジ 88
- Samsung Internet 15
- Firefox 78