【CSS】flex-basisの基本とwidthとの違い|優先順位・ショートハンドの罠・実践パターン

【CSS】flex-basisの基本とwidthとの違い|優先順位・ショートハンドの罠・実践パターン HTML/CSS

Flexbox でレイアウトを組んでいると、「width を指定したのに効かない」「flex-basiswidth はどう違うの?」という疑問に必ずぶつかります。

この記事では、flex-basis の役割を width との違いから整理し、優先順位の仕組みflex ショートハンドの罠min-width との関係実践的なレイアウトパターンまで解説します。

スポンサーリンク

flex-basis とは何か

flex-basis は、Flexbox の伸縮計算が行われる前の「理想サイズ」を指定するプロパティです。

.item {
  flex-basis: 200px;
}

この指定は「このアイテムは 200px を理想サイズとして扱い、その後に flex-grow / flex-shrink で余白を分配する」という意味です。

ポイントは、flex-basis最終的なサイズではないことです。あくまでレイアウト計算の「入力値」であり、コンテナの空き状況に応じて伸縮されます。

flex-basis と width の優先順位

Flexbox ではアイテムのサイズが以下の順序で決まります。

ステップ 参照するもの 説明
1 コンテンツサイズ テキストや画像の自然なサイズ
2 width(または height ボックスモデルの幅指定
3 flex-basis auto 以外が指定されていれば width より優先
4 min-width / max-width 最終的な制約として適用

つまり、flex-basisauto 以外の値で指定されていると、width は無視されます。

.item {
  width: 300px;
  flex-basis: 150px; /* ← こちらが優先される */
}

この場合、Flexbox の計算では 150px が基準になり、width: 300px は効きません。

flex-basis: auto の挙動

flex-basis: auto(デフォルト値)の場合は、以下の順序でサイズが決まります。

  1. width(または height)が指定されていれば、その値を使う
  2. widthauto なら、コンテンツのサイズを使う
/* width が効くパターン */
.item {
  flex-basis: auto; /* デフォルト */
  width: 250px;     /* ← この値が基準になる */
}

/* コンテンツサイズになるパターン */
.item {
  flex-basis: auto; /* デフォルト */
  /* width 指定なし → テキストや画像の幅が基準 */
}

まとめflex-basis: auto のときだけ width が効く。それ以外の値が指定されていると width は無視される。

flex-basis: 0 の意味

flex-basis: 0 は「全アイテムのスタートラインを 0 に揃える」という意味です。コンテンツサイズを無視し、コンテナの空き領域を flex-grow の比率だけで分配します。

.container {
  display: flex;
}
/* 全アイテムを均等幅にする */
.item {
  flex: 1; /* = flex: 1 1 0% → basis が 0 */
}

flex-basis: auto との違い

設定 基準サイズ 結果
flex-basis: 0 + flex-grow: 1 0px(コンテンツ無視) 全アイテムが均等幅になる
flex-basis: auto + flex-grow: 1 コンテンツサイズ テキスト量が多いアイテムが広くなる
<div class="container">
  <div class="a">短いテキスト</div>
  <div class="b">これは長いテキストです。コンテンツ量によって幅が変わります。</div>
</div>
.container { display: flex; gap: 16px; }

/* flex-basis: 0 → 均等幅 */
.a, .b { flex: 1 1 0%; }

/* flex-basis: auto → テキスト量で幅が変わる */
.a, .b { flex: 1 1 auto; }

flex ショートハンドと flex-basis の関係

実務では flex ショートハンドを使うことが多いですが、flex-basis の値が直感に反する値に設定されるケースがあります。

ショートハンド 展開値(grow shrink basis) 意味
flex: initial 0 1 auto 縮小するが拡大しない(デフォルト)
flex: 1 1 1 0% 均等に拡大・縮小(basis が 0 になる
flex: auto 1 1 auto コンテンツ基準で伸縮
flex: none 0 0 auto 伸縮なし(完全に固定)
flex: 0 0 1 0% 縮小のみ(拡大しない)

flex: 1 の罠

flex-basis の初期値は auto ですが、flex: 1 と書くと basis が 0% に変わります。

/* この2つは同じ意味 */
.item { flex: 1; }
.item { flex-grow: 1; flex-shrink: 1; flex-basis: 0%; }

/* これとは違う(basis が auto のまま) */
.item { flex-grow: 1; }

flex: 1 はすべてのアイテムを均等幅にしたいときに使います。コンテンツサイズを考慮したい場合は flex: 1 1 auto または flex: auto を使ってください。

flex-direction: column のとき

flex-basis主軸方向のサイズを指定します。flex-direction: column の場合、主軸が縦になるため、flex-basis高さ(height)として扱われます。

flex-direction flex-basis が制御するもの width/height との関係
row(デフォルト) width より優先
column 高さ height より優先
/* 横並び: flex-basis = 幅 */
.row-container {
  display: flex;
  flex-direction: row;
}
.row-item {
  flex-basis: 200px; /* 幅200px */
}

/* 縦並び: flex-basis = 高さ */
.col-container {
  display: flex;
  flex-direction: column;
  height: 400px;
}
.col-item {
  flex-basis: 100px; /* 高さ100px */
}

width は常に「幅」を指しますが、flex-basisflex-direction に応じて自動的に縦横が切り替わります。レスポンシブデザインで PC は横並び、スマホは縦並びに切り替える場合、flex-basis を使えば値を変更する必要がありません。

min-width との関係(テキストが溢れる問題)

Flexbox でアイテムの幅を指定しても、テキストがはみ出して崩れることがあります。

原因は、フレックスアイテムの min-width の初期値が auto であり、これがコンテンツの最小幅として機能するためです。つまり、コンテンツの幅より小さく縮小されません。

.container {
  display: flex;
}
.sidebar {
  flex: 0 0 200px; /* 200px固定のつもり */
}
.main {
  flex: 1;
  /* min-width: auto がデフォルト */
  /* → 長い英単語やURLが折り返されずはみ出す */
}

対処法min-width: 0 を明示的に指定します。

.main {
  flex: 1;
  min-width: 0;       /* ← 追加 */
  overflow-wrap: break-word; /* 長い単語を折り返す */
}

overflow: hidden でも解決しますが、意図せずコンテンツが切れる場合があるため、min-width: 0 の方が安全です。

実践パターン

パターン1:固定サイドバー + 可変メイン

.layout {
  display: flex;
  gap: 24px;
}
.sidebar {
  flex: 0 0 250px;  /* 伸縮なし、250px固定 */
}
.main {
  flex: 1;          /* 残りの幅を全て使う */
  min-width: 0;     /* テキスト溢れ防止 */
}

flex: 0 0 250px は「拡大しない・縮小しない・基準250px」の意味です。サイドバーが常に250px、メインが残りの幅になります。

パターン2:カードレイアウト(折り返しあり)

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.card {
  flex: 1 0 300px;  /* 最低300px、余白があれば拡大 */
}

flex: 1 0 300px は「拡大する・縮小しない・基準300px」の意味です。コンテナ幅に応じて3列→2列→1列に自動で折り返されます。

パターン3:入力フィールド + ボタン

.search {
  display: flex;
  gap: 8px;
}
.search input {
  flex: 1;          /* 残り幅を全て使う */
}
.search button {
  flex: none;       /* ボタンはコンテンツ幅で固定 */
}

flex: none(= 0 0 auto)でボタンを固定幅にし、入力フィールドが残りの幅を埋めます。

パターン4:均等分割ナビゲーション

.nav {
  display: flex;
}
.nav-item {
  flex: 1;          /* 全アイテムが均等幅 */
  text-align: center;
}

パターン5:不均等分割(2:1)

.container {
  display: flex;
  gap: 16px;
}
.wide {
  flex: 2;          /* 2/3 の幅 */
}
.narrow {
  flex: 1;          /* 1/3 の幅 */
}

flex-basis が効かない場合のチェックリスト

症状 原因 対処法
flex-basis を指定したのに幅が変わらない 親要素に display: flex がない 親に display: flex を追加
指定した幅より小さくなる flex-shrink: 1(デフォルト)で縮小されている flex-shrink: 0 を追加
指定した幅より大きくなる flex-grow: 1 で拡大されている flex-grow: 0 に変更
width を指定したのに効かない flex-basis が auto 以外に設定されている flex-basis: auto に変更
テキストが溢れる min-width: auto(デフォルト) min-width: 0 を追加

まとめ

項目 flex-basis width
役割 Flexbox の伸縮計算の基準サイズ ボックスモデルの
Flexbox での優先度 高い(auto 以外が指定されていれば width より優先) 低い(flex-basis: auto のときのみ有効)
flex-direction: column 高さとして機能する 常に幅のまま
最終サイズ flex-grow / flex-shrink で変動する 指定した値が最終サイズ

ポイント

  • flex-basisauto 以外なら width は無視される
  • flex: 1flex-basis: 0% になる(auto ではない)
  • 固定幅にしたいなら flex: 0 0 幅(または flex: none + width
  • テキスト溢れは min-width: 0 で解決
  • flex-direction: column では flex-basis は高さになる

あわせて読みたい