Kodokon kodokon.com

コンテナクエリとCSSネスティング

ビューポートではなくコンテナに対してコンポーネントをレスポンシブにし、ネイティブなネスティングでスタイルシートを構造化しましょう。

10 分 · 3 問

このレッスンを Kodokon で開く

メディアクエリはビューポートを測ります。狭いサイドバーとメインのグリッドの両方に表示されるカードは、メディアクエリでは正しく適応できません。同じ画面幅が2つの異なるコンテキストに対応するからです。コンテナクエリはこの分離を解決します。コンポーネントが自分のコンテナのサイズを問い合わせるのです。前提条件として、container-typeでコンテナを明示的に指定します(水平軸だけを測るinline-sizeが一般的なケース)。任意でcontainer-nameによって名前を付けられます。

CSS
.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}

@container sidebar (min-width: 400px) {
  .widget {
    display: grid;
    grid-template-columns: 80px 1fr;
    gap: 12px;
  }
}
画面ではなく自分の列に適応するウィジェット

コンテナ単位が絵を完成させます。1cqiは問い合わせ先のコンテナのインラインサイズの1%に等しくなります(cqwcqhcqbcqmincqmaxも存在します)。clamp()と組み合わせると、コンポーネントごとの流動的なタイポグラフィが生まれます。同じカードでも、どこに置かれても自分の列に見合った大きさのタイトルを得られます。

CSS
.card-slot {
  container-type: inline-size;
}

.card h2 {
  font-size: clamp(1rem, 5cqi, 1.75rem);
}

@container (max-width: 300px) {
  .card .meta {
    display: none;
  }
}
cqi単位とコンテナ名なしのクエリ

ネイティブなネスティングはついにプリプロセッサなしのネスティングをもたらします。&セレクタは親のコンテキストを参照し、メディアクエリと@containerはルールの中に直接ネストできます。Sassとの重要な違いは、ネストされた親が:is()で包まれたかのように扱われることです。帰結は2つあります。親がリストである場合、その詳細度は最も強いセレクタのものになります。そして& .childは文字列の連結を行いません。つまり、BEMの名前を生成するSassの&__elementパターンはネイティブには存在しません。

CSS
.menu {
  display: flex;
  gap: 8px;

  & > li {
    list-style: none;

    &:hover {
      background: #f3f4f6;
    }
  }

  @media (min-width: 768px) {
    gap: 16px;
  }
}
ネイティブなネスティング:状態、子孫、そしてメディアクエリ

理解度チェック

このレッスンの要点をしっかり覚えているか確認しましょう。

  1. 再利用可能なカードにとって、なぜメディアクエリよりコンテナクエリが好ましいのですか?
    • レンダリングエンジンが評価するのがより速いから
    • カードのコンテナのサイズに反応し、それは列が狭いどの画面でも同じだから
    • CSSの前提条件を宣言せずに機能するから
    • 幅に加えてビューポートの高さも問い合わせられるから
  2. 5cqiは何に相当しますか?
    • ビューポート幅の5%
    • 問い合わせ先のコンテナのインラインサイズの5%
    • コンテナのフォントサイズの5倍
  3. ネイティブなネスティングはSassのネスティングとどう違いますか?
    • ネイティブなネスティングはルールの中でメディアクエリをネストすることを禁じる
    • ネイティブなネスティングは親を:is()で包まれたものとして扱い、&__element風の連結を許さない
    • ネイティブなネスティングは&記号をコンパイルするためにプリプロセッサを必要とする
    • ネイティブなネスティングはネストを1階層に制限する