CSS のコンテナクエリでは cqi
や cqw
といった、基準となるコンテナ(Query Container)の相対的なサイズを表す特別な単位が使用できます。
以前の記事「CSS コンテナクエリ考察」でも少しだけ触れていますが、今回は、このコンテナクエリの単位の基本的な説明に加え、リキッドレイアウト、アスペクト比の保持、Masonry ライクなレイアウトの 3 つの活用方法をとおして、その可能性を考えていきます。
コンテナクエリの単位
見出し「コンテナクエリの単位」コンテナクエリで使用できる特別な単位(Container Query Length Units)は以下のとおりです。
単位 | 内容 |
---|---|
cqw | 基準コンテナの幅の 1% |
cqh | 基準コンテナの高さの 1% |
cqi | 基準コンテナのインラインサイズの 1% |
cqb | 基準コンテナのブロックサイズの 1% |
cqmin | cqi と cqb の小さい方の値 |
cqmax | cqi と cqb の大きい方の値 |
例えば 30cqi
であれば、基準となるコンテナの横幅 30% を意味します。
cqi
は論理プロパティなので、書字方向に応じて水平・垂直方向が変わりますが、この場合は横書き(writing-mode: horizontal-tb
)を前提としています。
参照されるサイズはもっとも近いコンテナ要素です。祖先要素をさかのぼっても container-type
が指定されている要素(基準コンテナ)が見つからない場合には、最終的に小さいビューポート(sv*
)が参照されます。
以下は、それぞれ 30cqi
、60cqi
、90cqi
を指定したデモです。
このように、@container
を使用しない場合であっても、container-type
を指定した基準コンテナがあれば、cqi
といった単位は有効です。
しかし、上記の例であればパーセント単位(%
)でも実現できるので、あまり恩恵は感じられません。もう少し別の使い方を探っていきます。
リキッドレイアウト
見出し「リキッドレイアウト」リキッドレイアウトを実現するには、ビューポートの単位(vw
)を使用することが一般的ですが、cqi
や cqw
を使用することで、コンポーネントのサイズを基準としたリキッドレイアウトが可能になります。
ビューポートベース
見出し「ビューポートベース」まずは、ビューポートの単位 vw
を使用した実装を見ていきます。
例えば、デザインカンプの幅が 375px
で、要素の内側の余白が 20px
、フォントサイズが 16px
であれば、リキッドレイアウトの指定は以下のようになります。
別のアプローチとしては、:root
に指定した基準となる変数を指定する方法が考えられます。変数に値や計算式を格納することで、それ以降の指定がシンプルになります。
3 番目のアプローチとして、:root
に font-size
を 10px
相当で指定し、各要素では rem
でサイズを指定する方法も考えられます。
先ほどよりさらにコードがシンプルになり、メンテナンス性が向上するのですが、ルート要素のフォントサイズを vw
(ビューポート幅)で指定した場合、ブラウザ側でフォントサイズの変更ができなくなるという、アクセシビリティ上の問題があるので避けたほうがよいでしょう。
以下に該当する WCAG 2.1 の達成基準を引用します。
ここまで、従来のビューポートベースでのリキッドレイアウトの例を紹介しましたが、続いて、コンテナクエリの単位を使用した例を見ていきます。
コンテナクエリベース
見出し「コンテナクエリベース」ビューポートベースでは、同じコンポーネントであっても、収まるレイアウトの幅に応じてスタイル調整が必要でしたが、コンテナクエリでは、基準となるコンテナのサイズに基づいたサイズが適用されるため、同一のコンポーネントをさまざまなレイアウトで使用することが可能になります。
例えば、デザインカンプにおけるカードコンポーネントの幅が 200px
で、要素の内側の余白が 20px
、フォントサイズが 16px
であれば以下の指定が考えられます。
以下はライブデモですが、スライダーを動かしてコンテナの幅を変更すると、余白(padding
)やフォントサイズ(font-size
)もあわせて変化します。
なお、値を変数に格納することもできますが、:root
に指定する方法とは異なり、基準となるコンテナごとに指定する必要があります。
このように、コンテナクエリベースでリキッドレイアウトを実現することができるのですが、コンポーネントの組み合わせによっては、余白やフォントサイズのバランスが悪くなる可能性もあるため、緻密な設計が求められるかもしれません。
リキッドレイアウトのメリット・デメリット
見出し「リキッドレイアウトのメリット・デメリット」ウェブサイトにおけるリキッドレイアウトの実装については、以下のメリット(Pros)と、デメリット(Cons)が考えられます。
メリット(Pros)
見出し「メリット(Pros)」- 拡大・縮小してもデザインカンプに近い印象を与えられる
- テキストの折り返し位置が変わらない
- 水平スクロールバーが発生しづらい
- 各デザインカンプの溝(中間サイズのレイアウト)を補完できる
リサイズしたときのレイアウトの変化が流麗であるという点も挙げられますが、ユーザが利用した際に気づく可能性は低いかもしれません。
デメリット(Cons)
見出し「デメリット(Cons)」- 実装や検証のコストが増加する
- コードが複雑になるためメンテナンス性が下がる
- テキストの可読性が損なわれ、アクセシビリティ上の問題が発生する可能性がある 1
- 絶対値(
px
)を指定した要素と競合してレイアウトが破綻する可能性がある
コンテナクエリベースでは、前述したように、コンポーネントの組み合わせによるバランス調整の難しさも挙げられます。
最終的にはウェブサイトの目的次第ですが、導入する際にはこれらの点を踏まえて慎重に検討したほうがよいでしょう。
アスペクト比の保持
見出し「アスペクト比の保持」cqi
や cqw
は、もう一方の軸である block-size
や height
に指定できるため、要素のアスペクト比(縦横比)を保持することができます。
例えば 16:9
のカードコンポーネントであれば、以下のようなコードになります。
アスペクト比の保持は、当然ながら aspect-ratio
を使用しても実現できますが、cqi
では min-*
や max-*
が使用できるという利点があります。
以下は、CSS グリッドを使用した 2 カラムレイアウトのコードです。
この 2 つを比較すると、コンテンツがアスペクト比に収まらないとき、隣り合うグリッドの見え方が異なります。cqi
では min-*
で指定しているため、隣り合うカードの高さがそろいますが、aspect-ratio
ではそろいません。
以下はライブデモです。contenteditable
属性を指定しているので、内容を編集して各要素の高さに違いを出すことができます。
Masonry レイアウト
見出し「Masonry レイアウト」最後に、Masonry のようなレイアウト2を考えてみます。
先にライブデモを確認します。スライダーを動かしてコンテナのサイズを変更しても、レイアウトは維持されたままになります。
以下にコードを抜粋しますが、フォントサイズ(font-size
)や、グリッド間の余白(gap
)を cqi
で指定しているため、比率を保ったまま拡大・縮小することができます。
<!-- HTML -->
<div class="masonry-container">
<div class="masonry">
<div></div>
<div></div>
<div></div>
<!-- ... -->
</div>
</div>
<!-- CSS -->
<style>
.masonry-container {
container-type: inline-size;
}
.masonry {
display: grid;
grid-template-columns: repeat(10, 1fr);
gap: 2cqi;
}
.masonry > div {
aspect-ratio: 1;
font-size: max(12px, 2cqi);
counter-increment: number;
}
.masonry > div:nth-child(3n) {
grid-column: span 2;
grid-row: span 2;
}
.masonry > div::after {
content: counter(number);
}
</style>
正直なところ、グリッドの行や列の指定でも cqi
をうまく使いたかったのですが、この例では font-size
と gap
に適用するにとどまりました。
ちなみに「実例で学ぶ CSS Subgrid」という記事では、10 × 10 のグリッドを作るために以下の指定をしています。このように、トラック数が明確なグリッドのスペースを確保するケースでは行や列にも cqi
の単位が使えそうです。
.map-container {
container-type: inline-size;
}
.map {
display: grid;
grid: repeat(10, 10cqi) / repeat(10, 10cqi);
}
おわりに
見出し「おわりに」この記事では、コンテナクエリの単位の活用方法を説明しました。まだまだコンテナクエリを本格的に使う機会も少ないため、もっと有用な使い方があるかもしれません。
もちろん、無理に使うものではありませんが、引き続きコンテナクエリの可能性を追求し、役立つテクニックやアイデアが見つかりましたら紹介できればと考えています。
脚注
-
最近のブラウザは、デフォルトの最小フォントサイズが
0
に設定されているので、どこまでも際限なく縮小してしまいます。以前は、Google Chrome が10px
、Safari が9px
でした。 ↩ -
CSS Grid Layout Module Level 3 の Editor’s Draft では、正式な Masonry Layout が提案されています。現時点では Firefox や Safari の機能フラグをオンにした状態、もしくは Firefox Nightly や Safari Technology Preview で一部の機能を試せますが、主要ブラウザでサポートされて安心して使えるようになるには、もう少し時間がかかりそうです。 ↩