CSSの進化が早い! スタイルクエリ(@container style())の基礎知識と便利な使い方を解説

コンテナクエリがすべてのモダンブラウザの安定版でサポートされ、これからはメディアクエリからコンテナクエリを使用する機会が増えてくると思います。

コンテナクエリは親コンテナに基づいてスタイルを定義できるものですが、親のサイズによるクエリだけではありません。親のスタイル値によるクエリ(スタイルクエリ)も可能です。スタイルクエリの基礎知識と便利な使い方を紹介します。

スタイルクエリを使用すると、複数のバリエーションを持つ再利用可能なコンポーネントが簡単に実装できます。

CSS スタイルクエリ(@container style())の基礎知識と便利な使い方を解説

Getting Started with Style Queries
by Una Kravets

下記は各ポイントを意訳したものです。
※元サイト様のライセンスに基づいて翻訳しています

CSSのスタイルクエリとは

親コンテナに基づいてスタイルを定義できるコンテナクエリとコンテナクエリの各単位は、ついにすべてのモダンブラウザの安定版でサポートされました。

コンテナクエリ単位のサポートブラウザ

コンテナクエリ単位のサポートブラウザ

コンテナクエリについて詳しくは、下記をご覧ください。

しかし、CSS Containment Module Level 3は、サイズによるクエリだけではありません。親のスタイル値によるクエリも可能です。Chrome 111でサポートされたスタイルクエリは、プロパティ値を親要素にクエリできるようになります。

これは、CSSでスタイルをさらに論理的に制御できることを意味します。アプリケーションのロジックやデータ層とスタイルからより適切に分離できるようにします。

サイズとスタイルのクエリをカバーするCSS Containment Module Level 3の仕様では、font-weight: 800;のようなプロパティと値を含むあらゆるスタイルを親からクエリできます。ただし、スタイルクエリは現在のところCSSのカスタムプロパティ値に対してのみ機能します。これはスタイルを組み合わせたり、データとデザインを分離したりするのに非常に便利な機能です。

それでは、カスタムプロパティでスタイルクエリを使用する方法を解説します。

スタイルクエリの使い方

下記のHTMLをご覧ください。

CSSのスタイルクエリを使用するには、最初にコンテナ要素を設定する必要があります。これは、直接または間接の親にクエリを実行するかどうかによって、異なるアプローチが必要になります。

直接の親に対するクエリ

直接の親に対するクエリ

直接の親に対するクエリ

スタイルクエリとは異なり、.cardがその直接の親のスタイルをクエリできるようにするために、.card-containercontainer-typeまたはcontainerプロパティを使用した包含する必要はありません。ただし、スタイル(この場合はカスタムプロパティ値)をコンテナ(この場合は.card-container)またはDOM内でスタイルを設定する要素を含む任意の要素に適用する必要があります。クエリで指定したスタイルをそのクエリを使用してスタイルしている直接の要素に適用してしまうと、無限ループを引き起こす可能性があるためです。

親を直接クエリするには、下記のように記述します。

スタイルクエリでは、クエリをstyle()で包んでいることに注目してください。これはサイズの値とスタイルを明確にするためです。

たとえば、コンテナの幅を指定するクエリは、@container (min-width: 200px) { … }と記述します。これは親コンテナの幅が200px以上であればスタイルを適用します。ただし、min-widthはプロパティにすることもできるので、スタイルクエリを使用してmin-widthのCSS値をクエリすることもできます。そのため違いを明確にするために、style()のラッパーを使用して、@container style(min-width: 200px) { … }と記述します。

間接の親に対するクエリ

間接の親、つまり直接の親ではない要素のスタイルをクエリする場合は、その要素にcontainer-nameを与える必要があります。

たとえば、.card-listcontainer-nameを与え、スタイルクエリでそれを参照することで、.card-listのスタイルに基づいて.cardにスタイルを適用できます。

通常、コンテナに名前を与えてクエリが何を参照するのかを明確にし、コンテナに簡単にアクセスできるようにすることがベストプラクティスです。これが役立つ例として、.card内の要素に直接スタイルを設定したい場合があります。.card-containerに名前が付いたコンテナがないと、直接クエリを実行することができません。

しかし、これらすべては実際にはもっと理にかなっています。いくつか例を見てみましょう。

スタイルクエリで実装したUIコンポーネント 1

スタイルクエリで実装したUIコンポーネント

スタイルクエリで実装したUIコンポーネント

スタイルクエリは複数のバリエーションを持つ再利用可能なコンポーネントすべてのスタイルを制御できなくても特定のケースで変更するコンポーネントで特に役立ちます。

この例では、同じカードコンポーネントを共有する一連のプロダクトのカードが表示されています。一部のカードには「New」「Low Stock」などが与えられていますが、これは--detailsというカスタムプロパティによってトリガーされています。プロダクトが在庫不足の「Low Stock」である場合、カードのボーダーはレッドになります。このタイプの情報はサーバーでレンダリングされる可能性が高いですが、下記のようにインラインのスタイルでカードで適用できます。

この構造化されたデータがあれば、値を-detailに渡すことができ、CSSのカスタムプロパティでスタイルを適用できます。

実際の動作は、下記のデモをご覧ください。

See the Pen
Style CQ Demo -- Commerce
by Una Kravets (@una)
on CodePen.

このCSSで--detail: low-stock--detail: newを適用できますが、コードブロックに冗長な部分があることに気がついたかもしれません。現在のところ、@container style(--detail)--detailの有無を照会する方法はありません。これによりスタイルの共有が向上し、繰り返しを少なくすることができます。この機能は現在、ワーキンググループで議論されています。

スタイルクエリで実装したUIコンポーネント 2

上記の例では、スタイルを適用するために複数の可能な値を持つ1つのカスタムプロパティを使用しました。しかし、複数のカスタムプロパティを使用してクエリを実行することで、それを混ぜることもできます。
お天気カードの例を見てましょう。

スタイルクエリで実装したUIコンポーネント

スタイルクエリで実装したUIコンポーネント

お天気カードの背景のグラデーションやアイコンのスタイルを設定するには、「cloudy」「rainy」「sunny」などの天気情報を探します。

こうすることで、天気情報に応じたスタイルを各カードに設定できます。しかし、メディアクエリのようにandを使用することでカスタムプロパティの組み合わせに対してスタイルを設定することもできます。

たとえば、曇りと晴れの両方がある日には「cloudy」「sunny」をandで記述します。

実際の動作は、下記のデモをご覧ください。

See the Pen
Style Queries Demo - Weather Cards
by web.dev (@web-dot-dev)
on CodePen.

スタイルクエリでさらに便利なのは、範囲値をクエリする機能です。
たとえば、--chanceOfRain: 50%というデータを送信し、@container style(30% <= --chanceOfRain < 60%)のように範囲を指定してスタイルを適用できます。このようにデザインやそのさまざまな組み合わせに対してより詳細な設定をすることができます。これもコンテナクエリのワーキンググループで活発に議論されているもう1つの機能です。

スタイルクエリでデータとデザインを分離する

上記の2つのデモは、適用されるスタイルからデータレイヤー(ページにレンダリングされるDOM)を分離する構造上の利点があります。スタイルはコンポーネントのスタイル内に存在する可能性のあるバリアントとして記述され、エンドポイントはコンポーネントのスタイル設定に使用するデータを送信できます。

1つ目では--detail値を更新する単一の値を使用し、2つ目では--rainy, --cloudy, --sunnyの複数の値を使用しました。さらに、値を組み合わせることも可能で、--cloudy--sunnyandで設定することで曇りと晴れの両方のスタイルを適用することもできます。

JavaScriptによるカスタムプロパティの値の更新は、DOMモデルの設定中 (つまりフレームワークでのコンポーネント構築) にも<parentElem>.style.setProperty('--myProperty’, <value>)による任意のタイミングでの更新にもシームレスに対応することができます。

下記は数行のコードでボタンの--themeを更新し、スタイルクエリとカスタムプロパティ(--theme)を使用してスタイルを適用するデモです。

スタイルクエリで実装したUIコンポーネント

スタイルクエリで実装したUIコンポーネント

実際の動作は、下記のデモをご覧ください。

See the Pen
Dynamic Style Query
by web.dev (@web-dot-dev)
on CodePen.

スタイルクエリを使用してカードのスタイルを設定しています。カスタムプロパティの値を更新するために使用するJavaScriptは下記のようになります。

この記事で解説した機能は、スタイルクエリのほんの始まりにすぎません。動的にレスポンシブなインターフェイスを構築するために、コンテナクエリにはさらに多くのことを期待できます。特にスタイルクエリに関しては、まだ未解決の問題がいくつかあります。1つはカスタムプロパティ以外のスタイルに対するスタイルクエリの実装です。これはすでに現在の仕様レベルで実装されていますが、まだどのブラウザにも実装されていません。また、ブーリアンコンテキスト評価については未解決の問題が解決されたときに現在の仕様レベルに追加される予定ですが、範囲クエリに関しては次の仕様レベルに予定されています。

sponsors

top of page

©2024 coliss