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

コンテナクエリが登場

うれしいお知らせです。ご要望の多かった機能の一つが、ウェブブラウザに実装されました。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 未満で、ResizeObserver と MutationObserver を使用して、安定したブラウザで現在使用可能な完全な @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 構文を完全にサポートします(構文的に有効なコメントであれば、どこにでも問題なく記述できます)。
  • 縦書きモード(筆記モードを使用)。
  • コンテナの相対単位(cqwcqh など)は、クエリ条件、プロパティ宣言、アニメーション キーフレーム内でサポートされます。 クエリ条件では remem がサポートされています。
  • 拡張コンテナクエリの構文: <ph type="x-smartling-placeholder">
      </ph>
    • 範囲の構文(例: (200px < width < 400px))。
    • 等式クエリ(例: (width = 200px))。
  • ::before::after などの疑似要素。
  • :is(...)/:where(...) のないブラウザは、オプションの回避策によってサポートされます。
  • orientationaspect-ratio の特徴クエリ。
  • 機能に基づいてクエリを正しくフィルタリングしました(たとえば、container: inline-size に対する height のクエリは横書きモードでは正しく禁止されます)。
  • DOM ミューテーション(例: <style> 要素や <link> 要素が実行時に削除)。
で確認できます。

ポリフィルの制限事項と警告

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

  • Shadow DOM はまだサポートされていません。
  • コンテナの相対単位(例: cqwcqh)は、@media クエリ条件ではサポートされていません。
    • Safari: 15.4 より前のアニメーション キーフレームでは、コンテナの相対単位はサポートされていません。
  • calc()min()max() などの数学関数は、クエリ条件ではまだサポートされていません。
  • このポリフィルは、インラインの同一オリジンの CSS でのみ機能します。クロスオリジン スタイルシート、および iframe 内のスタイルシート(ポリフィルが手動で読み込まれる場合を除く)はサポートされていません。
  • layoutstyle の封じ込めには、基盤となるブラウザのサポートが必要です。 <ph type="x-smartling-placeholder">
      </ph>
    • Safari 15.4 以降
    • Firefox では現在、スタイルの包含をサポートしていませんが、サポートに対応しています。

警告

  • FIDCLS に影響を与えないようにするため、ポリフィルは最初のレイアウトが同期的に読み込まれる場合でも、最初のレイアウトがいつ行われるかについては保証しません。ただし、LCP の不当な遅延を回避するためです。つまり、First Paint でこれに依存すべきではありません。
  • ResizeObserver Loop Errors を生成します。元のポリフィルもこれを行いますが、注目しておきましょう。これは、container-type: inline-size のブロックサイズがクエリの評価後に変化する可能性が高いものの、ResizeObserver にはブロックサイズの変更が重要でないことを示す方法がないためです。
  • このポリフィルをウェブ プラットフォーム テストでテストしたところ、70% の合格となりました。JavaScript API などの一部の機能はポリフィルされていないため、合格率を意図的に 70% に近づけています。
  • 次のバージョンより前のブラウザの 2.23% には、:where()回避策が必要です。 <ph type="x-smartling-placeholder">
      </ph>
    • サファリ 14
    • クロム 88
    • エッジ 88
    • Samsung インターネット 15
    • Firefox 78