ポリフィルの大規模な更新に伴い、コンテナクエリは安定版のブラウザに取り込まれ始める

コンテナクエリが利用可能に

デベロッパーから最も要望の多かった機能の一つが、ウェブブラウザで利用可能になりました。Chromium 105Safari 16 では、サイズベースのコンテナクエリを作成して、これらのブラウザでコンテナクエリの単位値を使用できるようになりました。サイズベースのコンテナクエリと cq 単位をより簡単に使用できるように、Chrome の Aurora チームは コンテナクエリ ポリフィルの更新に取り組んできました。これにより、より多くのブラウザとユースケースをサポートできるようになり、この強力な機能を安心してご利用いただけるようになりました。

コンテナクエリとは

コンテナ クエリは、親要素の特徴をターゲットにして子要素のスタイルを設定するスタイル設定ロジックを記述できる CSS 機能です。親のサイズをクエリすることで、真にコンポーネントベースのレスポンシブ デザインを作成できます。これは、ビューポートのサイズ情報のみを提供するメディアクエリとは異なり、より詳細で有用な情報です。

ALT_TEXT_HERE

コンテナクエリを使用すると、ページ内の場所に応じて異なる表示ができる再利用可能なコンポーネントを記述できます。これにより、ページやテンプレート全体で復元力と応答性が大幅に向上します。

コンテナクエリの使用

次のような 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%
cqmincqi または cqb の小さい方の値
cqmaxcqi または cqb の大きい値

コンテナベースの単位を使用する例として、レスポンシブ タイポグラフィがあります。ビューポートベースの単位(vhvbvwvi など)を使用して、画面上の任意の要素のサイズを指定できます。

.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 未満になり、MutationObserver で ResizeObserver を使用して、現在安定版のブラウザで利用可能な @container クエリ構文をすべてサポートします。

  • 個別のクエリ(width: 300pxmin-width: 300px)。
  • 範囲クエリ(200px < width < 400pxwidth < 400px)。
  • プロパティとキーフレーム内のコンテナの相対長さの単位(cqwcqhcqicqbcqmincqmax)。

コンテナ クエリ ポリフィルを使用する

ポリフィルを使用するには、ドキュメントのヘッダーに次のスクリプトタグを追加します。

<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 構文の完全なサポート(構文的に有効な場所にコメントを配置しても問題は発生しません)。
  • 縦書きモード(writing-mode 経由)。
  • コンテナ相対単位(cqwcqh など)は、クエリ条件、プロパティ宣言、アニメーション キーフレーム内でサポートされています。remem はクエリ条件でサポートされています。
  • 拡張コンテナクエリの構文:
    • 範囲の構文((200px < width < 400px) など)。
    • 等価クエリ((width = 200px) など)。
  • ::before::after などの疑似要素。
  • :is(...)/:where(...) のないブラウザは、オプションの回避策でサポートされています。
  • orientationaspect-ratio の特徴クエリ。
  • 機能に基づいてクエリを正しくフィルタリングする(たとえば、横書きモードでは container: inline-sizeheight をクエリすることは正しく禁止される)。
  • DOM の変更(実行時に <style> 要素と <link> 要素が削除されるなど)。

ポリフィルの制限と警告

コンテナクエリ ポリフィルを使用している場合、注意すべき機能がいくつか欠落しています。

  • Shadow DOM はまだサポートされていません。
  • コンテナ相対単位(cqwcqh など)は、@media クエリ条件ではサポートされていません。
    • Safari: コンテナ相対単位は、15.4 より前のアニメーション キーフレームではサポートされていません。
  • calc()min()max() などの数学関数は、クエリ条件ではまだサポートされていません。
  • このポリフィルは、インライン CSS と同一オリジン CSS でのみ機能します。クロスオリジンのスタイルシートと iframe 内のスタイルシート(ポリフィルが手動で読み込まれる場合を除く)はサポートされていません。
  • layoutstyle の制限には、基盤となるブラウザのサポートが必要です。

警告

  • FIDCLS に影響を与えないように、ポリフィルでは、最初のレイアウトがいつ行われるかについて保証しません。ただし、LCP の不当な遅延を回避しようとします。つまり、最初のペイントには使用しないでください。
  • ResizeObserver Loop Errors を生成します。元のポリフィルもこれを行うため、注意が必要です。これは、container-type: inline-size のブロックサイズはクエリの評価後に変更される可能性が高いが、ResizeObserver にはブロックサイズの変更を気にしないことを伝える方法がないことが原因です。
  • このポリフィルは Web Platform Tests でテストされ、70% の合格率を達成しました。JavaScript API などの特定の機能はポリフィル化されていないため、合格率は意図的に 70% に近づけられています。
  • :where()回避策は、以下のバージョンより古いブラウザを使用している 2.23% のユーザーに必要です。
    • Safari 14
    • Chromium 88
    • Edge 88
    • Samsung Internet 15
    • Firefox 78