メインコンテンツまでスキップ
  • Created:
  • Updated:
  • Author:
    Takeshi Takatsudo

Flexbox パターン

問題

Flexboxは最もよく使われるCSSレイアウトモデルですが、AIエージェントはしばしば誤った使い方をします。よくあるミスとしては、CSS Gridの方が適切な場面でflexboxを使う、オーバーフローを防ぐための min-width: 0 を忘れる、スティッキーフッターに flex-grow ではなく固定の高さを使う、flex軸を理解せずに justify-contentalign-items をデフォルトで使う、などがあります。

解決方法

Flexboxは一次元のレイアウトモデルです。単一の軸(行または列)に沿ってスペースを分配するのに優れています。コンポーネントレベルのレイアウト、ナビゲーションバー、ツールバー、アイテムが一方向に並ぶあらゆるシナリオに使いましょう。

コード例

センタリング(水平・垂直)

.centered-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
<div class="centered-container">
<div class="content">Perfectly centered</div>
</div>
Flexbox: センタリング

等しい高さのカラム

行コンテナ内のflexアイテムは、デフォルトで align-items: stretch により同じ高さに引き伸ばされます。

.columns {
display: flex;
gap: 1rem;
}

.column {
flex: 1;
/* No need for align-items or explicit height */
}
<div class="columns">
<div class="column">Short content</div>
<div class="column">
<p>Much longer content that determines the height of all columns.</p>
<p>All siblings will match this height automatically.</p>
</div>
<div class="column">Medium content here</div>
</div>
Flexbox: 等しい高さのカラム

スティッキーフッター

コンテンツが少ない場合はフッターがビューポートの下部に固定され、コンテンツが多い場合はコンテンツの下に自然に流れます。

body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}

main {
flex: 1;
}

/* header and footer need no special styles */
<body>
<header>Header</header>
<main>Main content</main>
<footer>Footer</footer>
</body>
Flexbox: スティッキーフッター

space-between と折り返しの問題

アイテムが折り返される場合、justify-content: space-between は最後の行に不自然な隙間を生じさせることがあります。一定のスペーシングには gap を使いましょう。

/* Problematic: last row items spread apart */
.bad-wrap {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

/* Better: consistent gaps between items */
.good-wrap {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}

.good-wrap > * {
flex: 0 1 calc(33.333% - 1rem);
}
Flexbox: space-between の折り返し問題 vs gap の解決策

min-width: 0 によるオーバーフロー防止

flexアイテムはデフォルトで min-width: auto を持ち、コンテンツサイズ以下に縮小できません。これにより制約のあるレイアウトでテキストのオーバーフローが発生します。

.card {
display: flex;
gap: 1rem;
}

.card-content {
flex: 1;
min-width: 0; /* Allow content to shrink and enable text-overflow */
}

.card-content h2 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

ナビゲーションバー

.navbar {
display: flex;
align-items: center;
gap: 1rem;
}

.navbar-logo {
margin-right: auto; /* Pushes nav items to the right */
}
<nav class="navbar">
<a class="navbar-logo" href="/">Logo</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>

AIがよくやるミス

  • 二次元レイアウトにflexboxを使う。 アイテムが行と列の両方で同時に揃う必要がある場合は、CSS Gridが正しい選択です。Flexboxは一方の軸のみを制御します。
  • スティッキーフッターに min-height: 100vh ではなく height: 100vh を使う。 固定の高さはコンテンツが長いページでオーバーフローを引き起こします。
  • flexアイテムに min-width: 0 を忘れる。 これがないと、flexアイテムはコンテンツの幅以下に縮小せず、水平方向のオーバーフローが発生します。
  • スペーシングに gap ではなく margin を使う。 flexアイテムのmarginはアイテムが隣接する部分でスペーシングが二重になり、先頭/末尾の子要素にワークアラウンドが必要になります。gap はアイテム間にのみ適用されます。
  • justify-content: space-betweenflex-wrap: wrap を併用する。 最後の行に予測不能な隙間ができます。代わりに gap と計算された flex-basis を使いましょう。
  • flex: 1 で十分なのに flex: 1 1 0 と書く。 ショートハンド flex: 1flex-grow: 1; flex-shrink: 1; flex-basis: 0% をすでに設定しています。
  • 不必要にflexコンテナをネストする。 シンプルな margin-right: autogap でスペーシングを実現できる場合は、追加のコンテナでアイテムを囲むのは避けましょう。

使い分け

Flexbox が適しているケース

  • 単一軸のレイアウト(ボタンの行、ナビゲーションバー、ツールバー)
  • サイズが不明または可変のアイテム間でスペースを分配する場合
  • コンテナ内でコンテンツを垂直センタリングする場合
  • コンポーネントレベルのレイアウト(カードの内部、フォーム行、メディアオブジェクト)
  • flex-direction: column を使ったスティッキーフッター

代わりにCSS Gridを使うべき場合

  • アイテムが行と列の両方で揃う必要がある場合(カードのグリッド)
  • 名前付きエリアを持つ複雑なページレベルのレイアウト
  • レスポンシブなグリッドへのアイテムの自動配置が必要な場合
  • アイテムが複数の行や列にまたがる必要がある場合

Tailwind CSS

Tailwindはすべてのflexboxプロパティに対応するユーティリティクラスを提供しています。以下は、この記事の主要なパターンをTailwindクラスで表現したものです。

センタリング

Tailwind: Flexbox センタリング

等しい高さのカラム

Tailwind: 等しい高さのカラム

スティッキーフッター

Tailwind: スティッキーフッター

参考リンク