yuheijotaki.com

CSS Container Queries を理解する

Container Queriesとは

MDNによると、「コンテナのサイズを見て、コンテナ内のスペースに応じてレイアウトを調整できる」とあります。

この「コンテナ」とは、基本的にスタイル指定を行うコンポーネントの親要素になります。

例えば、サイドバーとメインエリアで構成要素が同等のアイテムコンポーネントAがある場合、

  • サイドバーのアイテムコンポーネントAにとっては、サイドバーのエリア
  • メインエリアのアイテムコンポーネントAにとっては、メインのコンテンツエリア

のそれぞれが「コンテナ」に当たり、コンテナのサイズに応じてコンポーネントAのCSSの指定を書き分けることが可能 になります。

Container Queriesは現時点でFireFox以外のモダンブラウザでサポートされています。
FireFoxにも対応が必要な実際のプロジェクトでは、Polyfill を使用することが現実的な手法となりそうです。

Media Queriesとの違い

従来より使用しているMedia Queriesとの違いはどこにあるのでしょうか。

Media Queriesでは、基本的に画面のビューポート幅に応じてレイアウトを切り替えていました。
対してContainer Queriesは、コンテナ幅に基づいてコンポーネントのCSSを切り替えることができるため、これまでより柔軟かつシンプルにCSSを記述できるケースがでてきそうです。

この例のように構成要素が同等のコンポーネントが1画面内にある場合でも、画面のビューポート幅ではなく、それぞれのコンテナ幅から指定したスタイル適用ができます。

これまでは個別にコンポーネントに対してクラスを追加付与するなどの必要がありましたが、Container Queriesを使えばCSSのみでコンポーネントのスタイルを分岐させることができます。

使ってみる

これまで例で見てきたサイドバーとメインのエリアで、構成要素が同等のアイテムコンポーネントを簡素な形で書いてみました。

全体を div.wrapper で囲い div.sidebardiv.main を左右に配置します。
それぞれのアイテムリストは ul.list 、コンポーネントは li.item としてマークアップしています。

CSSのContainer Queriesの部分は下記のようになっています。

.list {
  container-type: inline-size;
}

@container(min-width:400px) {
  .item {
    display: flex;
  }
}

親のコンテナとなる ul.listcontainer-type: inline-size を指定します。

デフォルトはテキストが縦並び( display: block )になり、コンテナが400px以上の際はテキストが横並びになるようにするため、 @container(min-width:400px) {} の中に li.itemdisplay: flex するように記述します。

画面をリサイズしながら確認すると分かりやすいですが、ビューポート幅ではなくコンテナ幅によってスタイルの変更が適用されていることが確認できました。

まとめ

Container Queriesに初めて触れてみましたが、今後のレスポンシブデザインに対するアプローチに幅を持たせてくれるような機能だと感じました。

コンテナ幅でCSS指定ができることで、自由度が増す反面、デザインやコーディングのルールもより重要になってきます。
FigmaのAuto Layoutなどデザインツールで出来ることとの親和性も高そうですが、同時にデザイナーとの連携も密に行っていく必要がありそうです。

なかなかメリットのみ取り入れるのは難しいですが、特にコンポーネント指向の開発などではPolyfillを用いて取り入れることを検討してみても面白いと思いました。