CSS Grid / Flex レイアウトルール
この skill は、display: grid を第一候補にしつつ、display: flex の使いどころを絞り、視覚配置をコードへそのまま写すためのものです。
grid-template、空セル、grid-area 命名、flex-direction の選択を主に扱います。
ブレイクポイント、Container Queries、流体サイズの単位選定は ../kf-g-css-tak-responsive-rules/SKILL.md を優先し、gap と margin の責務分離は ../kf-g-css-spacing-gap-margin-rules/SKILL.md を優先します。
この skill を使う場面
display: gridとdisplay: flexのどちらを選ぶか決めるときgrid-templateとgrid-template-areasのどちらで書くか見直すときgrid-areaの命名ルールを決めるとき- 縦積みレイアウトを
gridで表現できないか検討するとき - AI が生成した CSS に、場当たり的な
flexが混ざっていないか確認するとき
最初に決めること
- その要素は本当にレイアウトコンテナにすべきか
- 視覚配置を
grid-templateでそのまま表現できないか flexが必要なのは一列方向の整列だけか- レイアウト名と見た目用クラス名を分離すべきか
選択順序
通常フロー
- 文書フローだけで成立する要素に、安易に
gridやflexを足さない。 - 見出し、本文、単純な縦積みが自然に流れるなら、まず通常フローのままで良い。
Grid
- セクション、カード、メディアオブジェクト、フォーム、情報パネルのように、行と列の関係で考えたほうが自然なレイアウトでは
gridを第一候補にする。 - 見た目を図として説明したくなるなら、まず
grid-templateで書けないか考える。 - 要素を縦に積みたいだけに見える場面でも、
gap、開始位置、将来の並び替えを考えるとgridのほうが崩れにくいことが多い。
Flex
flexは横一列の整列、両端寄せ、中央寄せ、折り返し可能な軽い並びに限定して使う。- 代表例は、ボタン群、チップ列、ツールバー、ナビゲーション、インライン方向の操作群である。
flexを選ぶ理由は、一方向の分配や整列で十分だからであり、二次元の配置や空白の設計が主題になった時点でgridに戻す。
Grid のルール
grid-template を最優先にする
- レイアウトを組むときは、まず
grid-templateで視覚的に表現できないか考える。 grid-template-areasよりgrid-templateを優先する。エリア名とトラックサイズを同じ場所に書けるため、見た目と実装の対応が崩れにくい。- 行文字列の中では、スペースを使ってカラムが視覚的に整列するように書く。
- 行と列のサイズを別宣言へ分散させず、読んだ瞬間に構造が分かる形を優先する。
.feature {
display: grid;
gap: 1rem 1.5rem;
grid-template:
"... title" auto
"media body " auto
"media meta " auto
/ 12rem 1fr;
}
空のグリッドセルを使う
- 空白がレイアウトの一部なら、空のグリッドセルを積極的に使う。
- 空セルは余白の代用品ではなく、構造を明示するために使う。
gapとmarginの使い分けは ../kf-g-css-spacing-gap-margin-rules/SKILL.md を参照する。
grid-area 名は [grid-area] で持つ
- class 名をそのまま
grid-area名のソースにしない。 - class は見た目や責務に対するセレクタとして使い、レイアウト上の面名は
[grid-area]属性へ分離する。 [grid-area]の値は、見た目ではなくレイアウト上の役割で命名する。- BEM 名や装飾クラスを、そのまま面名へ流し込まない。
- 共通 rule を置くなら、
*ではなく:where([grid-area])に限定する。 [grid-area]へ限定した共通 rule のパフォーマンス懸念は小さい。属性セレクタの一致対象が絞られ、grid-area自体も grid item にしか効かないためである。- ただし、
attr()をcontent以外で使う typed syntax は互換性がまだ揃っていない。基礎 CSS に入れる場合は、対応ブラウザが保証される案件か、@supports付きのプログレッシブエンハンスメントに限る。
<section class="feature">
<h1 class="feature-title" grid-area="title">タイトル</h1>
<div class="feature-media" grid-area="media">...</div>
<p class="feature-body" grid-area="body">...</p>
</section>
@supports (grid-area: attr(grid-area type(<custom-ident>), auto)) {
:where([grid-area]) {
grid-area: attr(grid-area type(<custom-ident>), auto);
}
}
- 面名の責務を class から切り離しておくと、見た目のクラス名変更でレイアウト定義まで巻き込まれにくい。
- Safari や Firefox まで広く保証したい案件では、この共通 rule を前提にせず、個別の
grid-area宣言をフォールバックとして持つ。
Flex のルール
flex は横一列の整列に絞る
- 一列方向の配列と分配だけで十分なら
flexを使ってよい。 - 横並びで
justify-content、align-items、flex-wrapを使いたい場面はflexが自然である。 - ただし、折り返した後の行同士の関係や列方向の揃いまで気になり始めたら
gridへ戻す。
.actions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
}
AI 出力の確認項目
grid-templateで書けるのに、grid-template-areasと行列定義が分かれていないか。- 行文字列のスペースが崩れていて、列の対応が読み取りにくくなっていないか。
grid-area名を class 名から流用していないか。grid-areaの共通 rule を*へ当てていないか。[grid-area]へ限定しているか。- typed
attr()を使う前提なのに、対応ブラウザや@supportsを無視していないか。 flexで二次元レイアウトを無理に組んでいないか。
出力時の方針
- まず
gridとflexのどちらを選ぶか、その理由を一文で明示する。 gridを選ぶ場合は、grid-templateで視覚構造を先に示す。flexを選ぶ場合は、一方向の整列だけで十分な理由を示す。[grid-area]を使う場合は、class とレイアウト名の責務分離を明示する。[grid-area]の共通 rule を使う場合は、パフォーマンスより互換性が論点であることと、[grid-area]限定かどうかを明示する。- 間隔責務が論点なら ../kf-g-css-spacing-gap-margin-rules/SKILL.md を併用する。
最終チェック
- 通常フローで足りる要素に
gridやflexを足していないか。 - 視覚配置を
grid-templateで表現できるのに、別の書き方へ逃げていないか。 - 列が読み取りやすいよう、行文字列のスペースが整列しているか。
grid-area名は[grid-area]へ分離されているか。- typed
attr()を使う共通 rule は:where([grid-area])へ限定し、@supportsか対応ブラウザ保証の条件があるか。 flexは横一列の整列に限定されているか。