最新CSS機能:ネスト、:has()、コンテナクエリ、subgrid
ライブデモで学ぶ最新CSS機能
最新CSS:ネスト、:has()、コンテナクエリ、subgrid | We.Inc
ネイティブのCSSネスト、:has()セレクター、コンテナクエリ、subgrid、@layer、:is()、color-mix()、text-wrap: balanceを、編集できるライブデモで紹介します。Baselineの対応表も掲載しています。
以前はSassやJavaScriptが必要だった処理を、今では素のCSSでこなせます。ネイティブのネストは関連するルールをまとめ、:has()は子要素に応じて親にスタイルを当て、コンテナクエリはコンポーネントを自身の幅に合わせ、subgridは入れ子の項目を外側のグリッドに揃えます。4つとも2023年にBaselineに到達しており、現在のブラウザーで使えます。
主な機能の概要
- :has()
- 親のクラスを切り替えるJavaScript
- コンテナサイズクエリ
- コンポーネント内でのビューポートのメディアクエリ
- subgrid
- カードの行を揃えるための固定の高さ指定
下の各機能には編集できるデモがあり、コンテナクエリのカードはスライダーに反応するので、ウィンドウのサイズを変えずにレイアウトの変化を確認できます。対応表には各機能がBaselineになった年を載せています。Baselineとは、最新のChrome、Edge、Firefox、Safariで動作するという意味です。
- コンテナクエリのデモで幅のスライダーをドラッグすると、カードが縦積みから横並びに切り替わる様子を確認できます。
- 左側の例はどれも編集できます。右側のサンドボックス内の結果は、入力に合わせて再描画されます。
- 公開前に対応表を確認しましょう。Baselineは4つの主要エンジンすべてを意味し、古いバージョンは含みません。
- 必要なスニペットをコピーしましょう。どれもビルド工程やライブラリを必要としません。
- ネストは浅く保ちましょう。通常は2階層で十分で、深いネストはSassのときと同じく、長くて詳細度の高いセレクターを生みます。
- コンテナクエリにはコンテナが必要です。まず親にcontainer-type: inline-sizeを指定しないと、@containerのルールは何にもマッチしません。
- 古いブラウザーの利用者を考慮する必要がある場合は、:has()のルールを@supports selector(:has(*))で囲み、きれいにフォールバックさせましょう。
- ライブラリやリセット用のスタイルには:where()を使いましょう。詳細度が0なので、誰でもクラス1つで上書きできます。
よくある質問
ネストのためにまだSassは必要?
ネストだけが目的なら不要です。ネイティブのネストは、ルールの中にルールを書く一般的なパターンと&セレクターに対応しています。Sassにはまだミックスイン、ループ、関数がありますが、かつてSassが使われていた用途の多くはカスタムプロパティとcolor-mix()に置き換わっています。
コンテナクエリとメディアクエリの違いは?
メディアクエリはビューポート、通常はウィンドウの幅を基準にします。コンテナクエリは指定した祖先要素を基準にします。そのため、1つのカードコンポーネントを、同じページの狭いサイドバーではコンパクトなレイアウトで、メインの列では横に広いレイアウトで表示できます。
:has()は遅い?
ブラウザーエンジンは実装前に最適化しており、通常の使い方なら問題ありません。巨大なページでbody:has(*)のような非常に広いセレクターを使うと、マッチング処理が増えるため、できるだけ:has()を特定のコンポーネントのクラスに結び付けましょう。
Baselineとは何ですか?
Baselineは、Webプラットフォームのコミュニティが付けるラベルで、ある機能がChrome、Edge、Firefox、Safariの現行バージョンで動作することを示します。Newly availableは、それらの最後のブラウザーが実装した日付です。Widely availableはその約30か月後になります。
入れ子のグリッドではなくsubgridを使うべきなのはどんなとき?
カードの行に並ぶタイトル、本文、ボタンのように、グリッドアイテムの子要素を外側のグリッドのトラックに揃える必要があるときはsubgridを使います。普通の入れ子のグリッドは独立したトラックを持つため、長さの異なる内容がずれてしまいます。
ネストでの&セレクターの仕組み
- ネストされたブロックの中では、&は外側のセレクターを表します。&:hoverは親自身に疑似クラスを付け、& + &は同じ種類の兄弟要素を対象にし、.theme-dark &は親を別の文脈の中に置きます。
- &のないネストされたセレクターは子孫として扱われるため、.card { p { } }は.card pという意味になります。2023年以降にリリースされたブラウザーは、ネストされたルールの先頭にpのような要素名だけを書く形式も受け付けます。
カスケードレイヤーの実践
- @layer reset, base, components, utilities; で最初に順序を宣言します。詳細度に関係なく後のレイヤーが前のレイヤーに勝つため、コンポーネントライブラリと自分の上書きスタイルの衝突のほとんどが解消されます。
- どのレイヤーにも属さないスタイルは、レイヤー内のすべてのスタイルに勝ちます。これは古いスタイルシートをレイヤー構成に移行するときに便利です。最初は既存のルールをレイヤー外に置いたままにし、1つずつ移していきましょう。
最初に取り入れる機能の選び方
- 利用者が最新のブラウザーを使っているなら、ネストと:is()はスタイルシートを短くするだけの、手軽に得られるメリットです。コンテナクエリは、異なる幅で表示される再利用可能なコンポーネントがあるときに効果を発揮します。subgridが最も役立つのは、カードグリッドとラベル付きのフォームです。
ネイティブのCSSネスト
ネストしたルールでスタイルを当てたカード
ホバー、タイトル、ダークバリエーションはすべて.cardの中にあります。&は.card自身を指します。
:has()親セレクター
チェックボックスがオンのときにフィールドを強調する
このフレームではスクリプトは動いていません。ラベルは中にチェック済みのinputがあることで、自らスタイルを変えています。
画像を含むときだけカードのレイアウトを変える
画像のないカードは1列のレイアウトのまま、画像のあるカードは2列になります。
コンテナクエリ
スライダーのデモの裏にあるCSS
container-typeによって.shelfの幅を測れるようになり、shelfの幅が420px以上になると@containerのルールがカードを横並びに切り替えます。
subgrid
テキストの長さに関係なく揃うカードの行
各カードは外側のグリッドの3行にまたがり、自身の行にsubgridを使うため、すべてのタイトル、本文、ボタンが同じ線に揃います。
@layer、:is()、:where()、color-mix()、text-wrap
カスケードレイヤーは順序で勝者を決める
IDセレクターは前のレイヤーにあるため、後のレイヤーにある単純なクラスが勝ちます。
:is()と:where()でセレクターリストを短くする
:is()は引数の中で最も強い詳細度を持ち、:where()は常に0として数えられます。
color-mix()で色合いとホバー時の濃淡を作る
oklab空間で白や黒と混ぜると、1つのブランドカラーから均等な色合いが作れます。
見出しにtext-wrap: balance
2つ目の見出しは、1語だけ取り残さずに単語を各行に均等に配分します。ブラウザーはバランス調整を数行程度の短いブロックに限定しています。
ブラウザーの対応状況(Baseline)
Baselineの状況(最新のChrome、Edge、Firefox、Safari)、2026年10月にMDNで確認
- :is() and :where()
- Widely available
- @layer(カスケードレイヤー)
- Widely available
- コンテナサイズクエリ(@container、container-type)
- コンテナスタイルクエリは別機能で、まだBaselineではありません。caniuseで確認してください
- CSSネスト
- ネストされたルールの先頭に要素名だけを書くには、2023年以降のリリースが必要
- text-wrap: balance
- 古いブラウザーは無視して通常どおり折り返す
コンテナクエリのデモ
下のカードは、ウィンドウではなくグレーのコンテナの幅に反応します。420pxを超えると2列のレイアウトに切り替わります。
コンテナの幅:
ウォールナットのデスクランプ
温かみのある光、真鍮のスイッチ、手作りのシェード。
@container (min-width: 420px) は{state}。
マッチ中:画像がテキストの横
マッチなし:画像がテキストの上
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る