
目次
親要素の幅に応じてスタイルを使い分けられるコンテナクエリーCSSは、モダンブラウザの実装も一巡して実用できる環境が整ってきました。すでにバリバリ使いこなしている方も多いのではないでしょうか。
本稿ではコンテナクエリーの仕様の中から、とても便利な「コンテナクエリーサイズ」というサイズ単位に絞って、少しでもお役に立つことが書ければと思います。まだコンテナクエリーを使ったことがない人でも、コンテナクエリーサイズは今日から即座に使えます。
コンテナクエリー仕様にくっついてきたコンテナクエリーサイズ(以下cqサイズ)は、数あるCSSの相対サイズ単位のうちのひとつです(しかし本当に増えましたね、単位)。名前はすべてcqから始まります(Container Queryの頭文字)。まずは基本的な使い方を見ていきましょう。
基本的な使い方
コンテナ宣言
まずはシンプルな例をひとつ。
<div class="container"><!-- cqサイズの基準にしたい要素 --> <div class="child"></div><!-- cqを使いたい要素 --> </div>
/* cqサイズの基準にしたい要素 */ .container { width: 500px; height: 300px; container-type: size; /* コンテナ宣言 */ } /* cqを使いたい要素 */ .child { width: 50cqw; /* コンテナの幅の50% ⇒ 250px */ height: 50cqh; /* コンテナの高さの50% ⇒ 150px */ }
サイズの基準にしたい先祖要素でコンテナ宣言するだけです。container-typeというプロパティがそれ。@containerルールを書かなくても、コンテナ宣言するだけでcqサイズは有効になります。
コンテナ宣言した(cqサイズの基準とする)要素をクエリーコンテナと呼びます(ややこしいので以下コンテナと呼びます)。コンテナは直接の親要素である必要はありません。コンテナ宣言をしている最も近い先祖がcqサイズの基準になります。
cqwはコンテナの幅の1/100、cqhは高さの1/100で、使い方はビューポートサイズ(vw/vh)ととてもよく似ています。vをcqに置き換えただけですので、vwやvhを使い慣れた方はすぐに馴染めると思います。
ちなみに、コンテナ宣言しないまま(先祖要素にコンテナがひとつもないまま)cqを使うと、サイズの基準はビューポートになり、結果はvw/vhと同じになります。
基準になるのは直近の先祖コンテナ
たとえば以下の例は子要素・孫要素ともにcqを使っていますが、同じコンテナをもとに寸法が決まっています。
<div class="container"> <div class="child"> <div class="grand-child"></div> </div> </div>
.container { width: 500px; height: 300px; container-type: size; /* コンテナ宣言 */ } .child { width: 75cqw; /* コンテナの幅の75% ⇒ 375px */ height: 75cqh; /* コンテナの高さの75% ⇒ 225px */ } .grand-child { width: 50cqw; /* コンテナの幅の50% ⇒ 250px */ height: 50cqh; /* コンテナの高さの50% ⇒ 150px */ }
.grand-childは親要素である.childを飛び越えて、コンテナである.containerの寸法を基準にしています。ここまでは、ビューポートサイズと同じです。
では、ほかにも参照できるコンテナがある場合はどうでしょう。
.container { width: 500px; height: 300px; container-type: size; /* コンテナ宣言① */ } .child { width: 75cqw; /* コンテナ①の幅の75% ⇒ 375px */ height: 75cqh; /* コンテナ①の高さの75% ⇒ 225px */ container-type: size; /* コンテナ宣言② ←New!! */ } .grand-child { width: 50cqw; /* コンテナ②の幅の50% ⇒ 187.5px */ height: 50cqh; /* コンテナ②の高さの50% ⇒ 112.5px */ }
(例が悪くてちょっと端数が出ちゃいましたが).grand-childのcqは祖父要素.containerではなく直近の親要素.childを基準にするようになりました。コンテナ宣言をしている最も近い先祖がcqサイズの基準になるのです。
コンテナサイズとborder、padding
cqサイズ計算の基準になるコンテナサイズには、borderとpaddingは含みません。box-sizingでいうところのcontent-boxが基準値となります。ここもビューポートサイズとは少し勝手が違うところですが、このほうがわかりやすいのは言うまでもありません。
下の例ではコンテナに20pxのborderと30pxのpaddingを設定しました。子要素が利用できるエリアは縦横100pxずつ減っていますが、cqもそのぶんだけ縮んでいます。
もっとも親しみやすいであろうcqw/cqhのほかにも、cqサイズにはさまざまな単位が用意されています。場面に応じて使い分けられるとよいですね。
size と inline-size
container-typeの値にはsizeとinline-sizeがあります。cqwとcqhの両方を使う場合にはsizeを、cqwだけが必要な場合にはinline-sizeを選びましょう。たとえば、メディアクエリーのようにコンテナの幅に応じたレイアウトの調整をするのであればinline-sizeが適当です。
container-type: size を指定した要素の高さは、内包するコンテンツの影響を受けなくなります。コンテンツを持っていても、コンテナじたいに明示的にheightを指定したりflexで膨らませたりしない限りペッタンコのままですし、コンテナの高さを上回るコンテンツは境界を越えて溢れ出ます(position: absoluteな子を持つ親要素のイメージが近いです)。したがって、コンテンツ量の成り行きで高さを下に伸ばしていきたい要素にはcontainer-type: sizeを設定することはできません。
下の例では子要素が親要素の底を突き破ってはみ出していますが、これが正しい挙動です。
.container { width: 500px; height: 100px; container-type: size; /* コンテナ宣言 */ } .child { width: 50cqw; /* コンテナの幅の50% ⇒ 250px */ height: 300cqh; /* コンテナの高さの300% ⇒ 300px */ }
察しの良い方はお気づきでしょう。これは無限ループを防ぐためです。もしコンテナの高さと子要素の高さが相関していたら、cqhを使った時に循環参照が起こりかねません。そこで、コンテナの高さは内包するコンテンツとは縁を切ってあるのです。
さまざまなcq単位
cqw | コンテナの幅の1/100 |
---|---|
cqh | コンテナの高さの1/100 |
cqi | コンテナのインラインサイズの1/100 |
cqb | コンテナのブロックサイズの1/100 |
cqmin | cqi, cqb のうち小さい方 |
cqmax | cqi, cqb のうち大きい方 |
※ インラインサイズ/ブロックサイズは書字方向によって軸が変わります
実践的な使い方
cqサイズが威力を発揮するのはコンテナのサイズが定まらない時です。間接的にサイズが決まる要素のサイズ計算は、時としてとても厄介です。
下の例は縦書きスマートフォンサイトのレイアウトです。コンテンツエリアの高さは、ヘッダーやフッターの出し入れにともなって変わります(MENUボタンを押すとヘッダーとフッターを出し入れできます)。
main { container-type: inline-size; h1 { font-size: 10cqi; } }
折り返しを発生させたくないh1見出しはフォントサイズをコンテンツエリアの高さに同調するようにしました(縦書きコンテンツなので「高さ=インライン軸」となるのがこのサンプルのチャームポイントです)。
このh1要素のフォントサイズをコンテナクエリーなしで算出するのはかなり厄介です。メニュー展開時と収納時の2パターンを用意しなければなりませんし、さらに、スマートフォン用ブラウザは作り付けのコンポーネントも上下から出たり引っ込んだりするので高さの算出にはdvhを使う必要があります。かてて加えて、コンテンツエリアにはpaddingが設定されていますからその数値を差し引いてようやくフォントサイズ算出の基準となるコンテンツエリアの有効高が求まります。
コンテナ宣言ひとつで、そうした回りくどい計算はすべて省略できます。
最後に
コンテナクエリーがテーマなのに@containerルールについて言及がひとつもないという珍しい記事になりました。コンテナに同調してサイズを決定するだけなら@containerルールは必須ではないということもついでにおわかりいただけたと思います。
この記事が、皆様のコンテナクエリー活動(コン活)に少しでも参考になりましたら倖いです。
この記事に関するご相談やご質問など、お気軽にお問い合わせください。
関連する記事
-
プロダクション
-
プロダクション
-
プロダクション