flexboxで子要素がはみ出す・縮まない原因と直し方(min-width:autoの罠)

症状:flexアイテムが縮まず、親からはみ出す

display: flex のレイアウトで、長い文章やテーブル、画像を入れた子要素だけが縮まず、親の幅を押し広げてはみ出す。flex: 1 を付けて可変にしたはずなのに、思ったより幅が広がって横スクロールが出たり、text-overflow: ellipsis の「…」が出なかったりする。

原因のほとんどは、flexアイテムの min-width の初期値が auto であることです。この値のせいで、flexアイテムは「中身の最小幅」より小さくは縮まないルールになっています。要素そのものより先に、この既定の挙動を知るのが近道です。

原因は min-width: auto の一点に集約される

flexboxのはみ出しは、次の1つの仕様がすべての入口です。ここから3つの典型パターンに枝分かれします。

flexアイテムの min-width / min-height の初期値は 0 ではなく autoauto は「中身がはみ出さない最小サイズ」を意味するため、flexアイテムはその最小サイズより小さく縮まない。

通常のブロック要素の min-width0 です。ところがflexアイテム(flexコンテナの直接の子)だけは auto が初期値になります。flex: 1flex-shrink: 1 で「縮んでいいよ」と指定しても、min-width: auto が縮小の下限を「中身の幅」に固定してしまうため、長い中身があると縮まずに親を押し広げます。

パターン1:折り返さない長いテキストが縮まない

URLや空白のない長い文字列、あるいは white-space: nowrap を付けたテキストが、flexアイテムの最小幅を押し上げてはみ出す。

パターン2:中のテーブルが親を押し広げる

flexアイテムの中に table や横に長いコンテンツがあると、overflow-x: auto を付けてもスクロールにならず、テーブルの実寸まで枠が広がる。

パターン3:画像が元の幅のままはみ出す

大きな画像を入れると、max-width: 100% が効かず元のピクセル幅で表示され、親をはみ出す。

いずれも直し方の軸は同じで、縮ませたいflexアイテムに min-width: 0 を明示することです。以下、パターンごとに失敗デモと修正デモを並べます。

パターン1:折り返さない長いテキストが縮まない

アバターと本文を横並びにした、よくあるリスト項目です。本文側に flex: 1 を付けているのに、長いタイトルや text-overflow: ellipsis を付けたテキストが縮まず、右にはみ出します。ellipsis の「…」が出ないのは、そもそも要素が縮んでいない(省略が発生する幅まで狭まっていない)からです。

下のデモは同じマークアップで、右側だけ本文に min-width: 0 を付けています。枠(点線)からのはみ出し方の違いを見てください。

はみ出すパターン(min-width: auto のまま)

本文が縮まず、テキストが枠からはみ出します。ellipsisの「…」も出ません。

AB
田中 太郎
https://example.com/very/long/path/that-should-be-truncated-but-is-not
直したパターン(min-width: 0 を付ける)

本文が枠内に収まり、あふれたテキストは「…」で省略されます。

AB
田中 太郎
https://example.com/very/long/path/that-should-be-truncated-but-is-not
.row {
  display: flex;
  gap: 10px;
}

/* はみ出す:flex アイテムの min-width が auto(初期値)
   → 中身の最小幅より小さく縮まない */
.body {
  flex: 1;
}

/* 直す:min-width: 0 で「中身より小さくてもよい」と伝える */
.body {
  flex: 1;
  min-width: 0; /* これで縮めるようになる */
}

/* ここまで来て初めて text-overflow: ellipsis が効く */
.body .text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

ここが連鎖のポイント:text-overflow: ellipsis は「要素の幅を超えた分」を省略する仕組みです。min-width: auto のflexアイテムは中身の幅まで広がってしまうので、超過分が生まれず「…」が出ません。ellipsis が効かないときは、その要素かflexの親のどこかに min-width: 0 が足りていないケースが多いです。ellipsisが効かない原因はほかにも width 未指定や white-space: nowrap 忘れなどがあり、チェックリスト形式でまとめて確認したい場合は「CSSでテキストが折り返されない・省略されない原因と直し方」もあわせてどうぞ。

自分のケースか確認する方法:DevToolsで縮まないflexアイテムを選び、Computedパネルで min-width の値を見ます。auto になっていればこの原因です。試しに min-width: 0 を書き足して収まるかを確認してください。

パターン2:中のテーブルが親を押し広げる

サイドバーとメインを横並びにし、メイン側に横長のテーブルを置いた構成です。テーブルを囲む divoverflow-x: auto を付けて「はみ出したら横スクロール」を狙っても、flexアイテム側が min-width: auto のままだと、枠がテーブルの実寸まで広がってスクロールになりません。結果、ページ全体に横スクロールが出ます。

下のデモは、テーブルを囲むflexアイテムに min-width: 0 を付けているかどうかだけが違います。

はみ出すパターン(overflow だけ・min-width: auto)

overflow-x: auto を付けてもスクロールにならず、テーブルの実寸まで枠が広がります。

Nav
注文ID顧客名商品金額ステータス
ORD-1001山田商事株式会社プレミアムプラン年額¥120,000入金確認済み
ORD-1002佐藤デザイン事務所スタンダードプラン¥48,000発送準備中
直したパターン(min-width: 0 + overflow-x: auto)

flexアイテムが縮めるようになり、あふれたテーブルは枠内で横スクロールします。

Nav
注文ID顧客名商品金額ステータス
ORD-1001山田商事株式会社プレミアムプラン年額¥120,000入金確認済み
ORD-1002佐藤デザイン事務所スタンダードプラン¥48,000発送準備中
.layout {
  display: flex;
}

/* はみ出す:min-width: auto なので、
   中のテーブルの実寸まで枠が広がってしまう */
.main {
  flex: 1;
}
.table-scroll {
  overflow-x: auto; /* 枠が広がるので、この overflow が発動しない */
}

/* 直す:flex アイテムを縮めるようにしてから overflow を効かせる */
.main {
  flex: 1;
  min-width: 0; /* これが先。無いと overflow-x は効かない */
}
.table-scroll {
  overflow-x: auto; /* ここで初めて枠内スクロールになる */
}

overflow-x: automin-width: 0 の関係は「順番」で考えると分かりやすいです。overflow は「親の幅を超えた分をスクロールにする」機能なので、親が中身に合わせて広がってしまうと、そもそも超過が発生せずスクロールになりません。先に min-width: 0 で親を縮められる状態にしてから、overflow-x: auto ではみ出しをスクロールに変える、という2段構えです。

自分のケースか確認する方法:横スクロールが出る要素の親をさかのぼり、flexアイテムに min-width: 0 が付いているかを確認します。overflow を付けたのにスクロールにならない場合は、ほぼこの min-width 不足です。

パターン3:画像が元の幅のままはみ出す

画像に width: 340px のような具体的な幅を指定していると、その幅がそのままflexアイテムの最小サイズの下限になり、flex-shrink が効いていても縮まずに親をはみ出します(ここでは実際に <img> 要素・幅340pxのSVG画像で再現しています)。

下のデモは、画像に固定の width を指定しているか、代わりに max-width: 100% にしているかの違いです。左ははみ出したまま、右は画像が親に合わせて縮みます。

はみ出すパターン(width: 340px を指定)

画像が元の幅(340px)のまま表示され、枠をはみ出します。

画像の右に説明テキストを置いた構成です。
直したパターン(width を外し max-width: 100%)

画像が親の幅に合わせて縮み、枠内に収まります。

画像の右に説明テキストを置いた構成です。
.card {
  display: flex;
  gap: 10px;
}

/* はみ出す:width を指定すると、その幅が縮小の下限になり親を押し広げる */
.card img {
  width: 340px;
}

/* 直す:固定の width をやめ、max-width で縮小を許可する */
.card img {
  max-width: 100%;
  height: auto;
}

画像の場合は、固定の width をやめて max-width: 100%(+アスペクト比を保つ height: auto)にするのが基本の対策です。画像を div などでラップしている構成では、そのラッパー側が min-width: auto で広がっていることもあるので、あわせて min-width: 0 を足すと確実です。

min-width: 0 と overflow: hidden の使い分け

flexのはみ出し対策として min-width: 0overflow: hidden はよく混同されますが、役割が違います。どちらを使うかは「はみ出した中身をどうしたいか」で決めます。

min-width: 0 は「縮めるようにする」

flexアイテムの縮小の下限を解除して、親に収まるように縮める。これがはみ出しの根本対策で、まず最初に試すべき指定。ellipsis やレスポンシブな折り返しはこれが前提になる。

overflow: hidden は「あふれた分を隠す」

min-width: 0 と同時に指定すると、flexアイテムを縮小可能にする副作用も持つ(overflowvisible 以外だと最小幅の計算が変わるため)。ただし目的は「見えなくする」ことなので、単独で使うと中身が切れて読めなくなる。

実務では、まず min-width: 0 で縮められる状態を作り、その上で用途に応じて overflow-x: auto(スクロールさせる)か text-overflow: ellipsis(省略する)を選ぶのがきれいです。overflow: hidden を単独で貼るのは、切れても構わない装飾要素に限る、と決めておくと崩れにくくなります。

縮ませたいなら min-width: 0、スクロールさせたいなら min-width: 0 + overflow-x: auto、省略したいなら min-width: 0 + overflow: hidden + text-overflow: ellipsis。起点はいつも min-width: 0。

直らないときの切り分け手順

3つのデモを見ても収まらない場合は、次の順で確認します。flexのはみ出しは「どのflexアイテムが縮んでいないか」を特定するのが先決です。

手順1:はみ出している要素のflex親を特定する

DevToolsではみ出した要素を選び、親をさかのぼって display: flex のコンテナを探す。その直接の子(flexアイテム)が縮まない犯人。

手順2:そのflexアイテムのmin-widthを見る

Computedパネルで min-widthauto なら、min-width: 0 を書き足す。多くはこれで収まる。

手順3:ネストしている場合は各階層に付ける

flexの中のflexのように入れ子だと、内側のflexアイテムにも min-width: 0 が要る。外側だけ直しても内側で押し広げられるので、はみ出す階層まで順に付ける。

まとめ

flexboxで子要素がはみ出す・縮まないときは、flexアイテムの min-width の初期値が auto であることを思い出すのが近道です。長いテキストもテーブルも画像も、入口は同じこの一点です。

縮まないflexアイテムを見つける → min-width: 0 を付ける → 用途に応じて overflow-x: auto か text-overflow: ellipsis を足す。

この順で潰せば、実務で出会うflexのはみ出しはほぼ収まります。text-overflow: ellipsis が効かないときも、まずは min-width: 0 が足りているかを疑ってください。テーブルを含むレイアウトの横スクロール制御は、min-width: 0overflow-x: auto をセットで使うのが定番です。

同じシリーズの関連記事

「効かない・動かない」トラブル解決シリーズの記事です。症状から原因を切り分けたいときにあわせてどうぞ。

関連するUI事例

flexレイアウトやテーブルのはみ出し制御を、実際に動くコードで確認できる事例です。