CSS コンテナー クエリは依然として勢いを増しており、私たちの多くは、小さな実験やその他の目的であっても、それらに手を染めています。 彼らは素晴らしいですが、完全ではありません。 ブラウザのサポート — 一部のプロジェクトでそれらを使用することを正当化するには十分ですが、交換を開始したくなるほどではないかもしれません メディアクエリ 光沢のある新しいコンテナー サイズ クエリを使用した過去のプロジェクトから。
彼らは確かに便利です! 実際、私はすでにいくつかの状況に出くわしましたが、本当にそれらに手を差し伸べたいと思っていましたが、サポート要件を克服できませんでした. もし私がそれらを使うことができたなら、それはそのような状況でどのように見えるかでした.
この記事の執筆時点では、次のデモはすべて Chrome または Safari で最適に表示されます。 Firefox は 船のサポート バージョン 109 で。
ケース 1: カード グリッド
あなたはこれを期待しなければなりませんでしたよね? これは非常に一般的なパターンであり、私たち全員がある時点でそれに遭遇するようです. しかし実際のところ、コンテナ サイズ クエリは、標準的なメディア クエリよりも優れた結果をもたらし、時間を大幅に節約できたはずです。
各カードが 1:1 の縦横比を維持する必要があるこのカード グリッドを構築する任務を負っているとします。
見た目以上にタフ! 問題は、コンポーネントのコンテンツをビューポートの幅に合わせてサイズ変更すると、コンポーネントがビューポートにどのように応答するか、および他の祖先コンテナがそれに応答する方法に翻弄されることです。 たとえば、カードが特定のインライン サイズに達したときにカードの見出しのフォント サイズを小さくしたい場合、信頼できる方法はありません。
でフォントサイズを設定できます vw
ユニットだと思いますが、コンポーネントはまだブラウザーのビューポート幅に関連付けられています。 また、同じブレークポイントを持たない可能性のあるコンテキストでカード グリッドを使用すると、問題が発生する可能性があります。
私の実際のプロジェクトでは、次のような JavaScript アプローチにたどり着きました。
- サイズ変更イベントをリッスンします。
- 各カードの幅を計算します。
- 幅に基づいて各カードにインライン フォント サイズを追加します。
- を使用して内部のすべてをスタイルします
em
単位
大変な作業のようですね。 しかし、さまざまなコンテキストでさまざまな画面サイズにわたって必要なスケーリングを得るための安定したソリューションです。
コンテナクエリは、私たちに提供するので、はるかに優れていたでしょう コンテナー クエリ ユニット、など cqw
単位。 もうお分かりかもしれませんが、 1cqw
等しい 1%
コンテナの幅。 また、 cqi
コンテナのインライン幅の尺度である単位、および cqb
コンテナのブロック幅。 したがって、カードコンテナが 500px
広く、 50cqw
値は次のように計算されます 250px
.
カード グリッドでコンテナー クエリを使用できた場合、 .card
コンテナとしてのコンポーネント:
.card {
container: card / size;
}
次に、内側のラッパーを設定することもできました padding
スケールする 10%
.card
の幅 cqw
単位:
.card__inner {
padding: 10cqw;
}
これは、特定のビューポート幅でカードが使用される場所に関係なく、カードの端とその内容の間の間隔を一貫してスケーリングするための優れた方法です。 メディア クエリは必要ありません。
別のアイデア? 使用する cqw
内部コンテンツのフォントサイズの単位、次にパディングを適用します em
単位:
.card__inner {
font-size: 5cqw;
padding: 2em;
}
5cqw
は任意の値であり、私が決めた値です。 そのパディングはまだ等しい 10cqw
から em
単位は .card__inner
フォントサイズ!
あなたはそれをキャッチしましたか? の 2em
に関連しています 5cqw
設定されているフォントサイズ 同じコンテナに. コンテナーは、私たちが慣れ親しんでいるものとは異なる働きをします。 em
単位は同じ要素の相対値です font-size value
. しかし、すぐに気づいたのは、コンテナ クエリ ユニットが関連していることです。 コンテナでもある最も近い親.
たとえば、 5cqw
に基づいてスケーリングしません。 .card
この例の要素の幅:
.card {
container: card / size;
container-name: card;
font-size: 5cqw;
}
むしろ、コンテナーとして定義されている最も近い親に合わせてスケーリングされます。 それが私が設定した理由です .card__inner
ラッパー。
ケース 2: 交互レイアウト
別のプロジェクトでさらに別のカード コンポーネントが必要でした。 今回は、カードを横向きのレイアウトから縦向きのレイアウトに移行する必要がありました。その後、横向きに戻し、画面が小さくなると再び縦向きに戻します。
私は、このコンポーネントをこれら XNUMX つの特定のビューポート範囲で縦向きにするという汚い仕事をしました ( 新しいメディア クエリ範囲構文!)、しかし問題は、メディア クエリ セット、その親、およびビューポートの幅に応答する可能性のあるその他のものにロックされることです。 内容がどこで壊れるのだろうと心配せずに、どんな状況でも機能するものを望んでいます!
コンテナ クエリを使用すると、これが簡単になります。 @container
ルール:
.info-card {
container-type: inline-size;
container-name: info-card;
}
@container info-card (max-width: 500px) {
.info-card__inner {
flex-direction: column;
}
}
XNUMX つのクエリ、無限の流動性:
でもちょっと待って! 注意していただきたいことがあります。 具体的には、小道具ベースのデザイン システム内でこのようなコンテナー クエリを使用するのは難しい場合があります。 たとえば、これ .info-card
コンポーネントには、小道具に依存して外観を変更する子コンポーネントを含めることができます。
なぜそれが大したことなのですか? カードの縦向きのレイアウトでは代替スタイルが必要になる場合がありますが、JavaScript の props を CSS で変更することはできません。 そのため、必要なスタイルを複製するリスクがあります。 これには実際に触れて、 別の記事で回避する方法. 大量のスタイリングにコンテナ クエリを使用する必要がある場合は、メディア クエリに重きを置いている既存のデザイン システムにコンテナ クエリを押し込むのではなく、コンテナ クエリに基づいてデザイン システム全体を構築する必要がある場合があります。
ケース 3: SVG ストローク
私が最近使用したもう XNUMX つの非常に一般的なパターンを次に示します。ここでは、コンテナー サイズのクエリを使用すると、より洗練された製品が得られます。 見出しでロックされたアイコンがあるとします。
Heading
メディア クエリがなくても、タイトルのサイズに合わせてアイコンを拡大縮小するのは非常に簡単です。 ただし、問題は、SVG の stroke-width
小さいサイズでは細すぎて目立たないかもしれませんし、大きいサイズでは非常に太いストロークで注目を集めすぎるかもしれません。
サイズとストローク幅を決定するために、クラスを作成して各アイコン インスタンスに適用する必要がありました。 アイコンが固定フォント サイズでスタイル設定された見出しの横にある場合は問題ないと思いますが、常に変化する流動的なタイプで作業する場合はあまり良くありません。
見出しのフォント サイズは、ビューポートの幅に基づいている可能性があるため、SVG アイコンは、ストロークが任意のサイズで機能する場所に応じて調整する必要があります。 見出しの相対的なストローク幅を作成できます font-size
にセットすることで em
ユニット。 しかし、従わなければならない特定のストローク サイズのセットがある場合、これはうまくいきません。 stroke-width
ビューポート幅でメディアクエリに頼ることなく、特定のポイントでの値。
しかし、その時点でコンテナー クエリの余裕があれば、次のようにします。
.icon {
container: icon / size;
width: 1em;
height: 1em;
}
.icon svg {
width: 100%;
height: 100%;
fill: none;
stroke: #ccc;
stroke-width: 0.8;
}
@container icon (max-width: 70px) {
.icon svg {
stroke-width: 1.5;
}
}
@container icon (max-width: 35px) {
.icon svg {
stroke-width: 3;
}
}
実装を比較して、コンテナ クエリ バージョンが SVG のストロークを、コンテナの幅に基づいて必要な特定の幅にスナップする方法を確認してください。
おまけ: 他の種類のコンテナ サイズ クエリ
OK、実際のプロジェクトで実際にこれに遭遇したことはありません。 しかし、コンテナー クエリに関する情報を調べていたときに、コンテナーのサイズや物理的な寸法に関連する、コンテナーについてクエリできる追加事項があることに気付きました。
私が見たほとんどの例は、 width
, max-width
, min-width
, height
, block-size
, inline-size
この記事全体で行ってきたように。
@container info-card (max-width: 500px) {
.info-card__inner {
flex-direction: column;
}
}
だけど MDN はさらに XNUMX つのことを概説しています に対してクエリを実行できます。 一つは orientation
メディアクエリで常に使用しているため、これは完全に理にかなっています。 コンテナー クエリでも同じです。
@media screen (orientation: landscape) {
.info-card__inner {
/* Style away! */
}
}
@container info-card (orientation: landscape) {
.info-card__inner {
/* Style away! */
}
}
他の? これは aspect-ratio
、 信じようと信じまいと:
@container info-card (aspect-ratio: 3/2) {
.info-card__inner {
/* Style away! */
}
}
両方の例を試してみる編集可能なデモを次に示します。
これらのいずれかの適切な使用例はまだ見つかっていません。 何かアイデアがある場合や、プロジェクトで役立つと思われる場合は、コメントでお知らせください。