症状: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ではなくauto。autoは「中身がはみ出さない最小サイズ」を意味するため、flexアイテムはその最小サイズより小さく縮まない。
通常のブロック要素の min-width は 0 です。ところがflexアイテム(flexコンテナの直接の子)だけは auto が初期値になります。flex: 1 や flex-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 を付けています。枠(点線)からのはみ出し方の違いを見てください。
本文が縮まず、テキストが枠からはみ出します。ellipsisの「…」も出ません。
本文が枠内に収まり、あふれたテキストは「…」で省略されます。
.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:中のテーブルが親を押し広げる
サイドバーとメインを横並びにし、メイン側に横長のテーブルを置いた構成です。テーブルを囲む div に overflow-x: auto を付けて「はみ出したら横スクロール」を狙っても、flexアイテム側が min-width: auto のままだと、枠がテーブルの実寸まで広がってスクロールになりません。結果、ページ全体に横スクロールが出ます。
下のデモは、テーブルを囲むflexアイテムに min-width: 0 を付けているかどうかだけが違います。
overflow-x: auto を付けてもスクロールにならず、テーブルの実寸まで枠が広がります。
| 注文ID | 顧客名 | 商品 | 金額 | ステータス |
|---|---|---|---|---|
| ORD-1001 | 山田商事株式会社 | プレミアムプラン年額 | ¥120,000 | 入金確認済み |
| ORD-1002 | 佐藤デザイン事務所 | スタンダードプラン | ¥48,000 | 発送準備中 |
flexアイテムが縮めるようになり、あふれたテーブルは枠内で横スクロールします。
| 注文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: auto と min-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% にしているかの違いです。左ははみ出したまま、右は画像が親に合わせて縮みます。
画像が元の幅(340px)のまま表示され、枠をはみ出します。
画像が親の幅に合わせて縮み、枠内に収まります。
.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: 0 と overflow: hidden はよく混同されますが、役割が違います。どちらを使うかは「はみ出した中身をどうしたいか」で決めます。
min-width: 0 は「縮めるようにする」
flexアイテムの縮小の下限を解除して、親に収まるように縮める。これがはみ出しの根本対策で、まず最初に試すべき指定。ellipsis やレスポンシブな折り返しはこれが前提になる。
overflow: hidden は「あふれた分を隠す」
min-width: 0 と同時に指定すると、flexアイテムを縮小可能にする副作用も持つ(overflow が visible 以外だと最小幅の計算が変わるため)。ただし目的は「見えなくする」ことなので、単独で使うと中身が切れて読めなくなる。
実務では、まず 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-width が auto なら、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: 0 と overflow-x: auto をセットで使うのが定番です。
同じシリーズの関連記事
「効かない・動かない」トラブル解決シリーズの記事です。症状から原因を切り分けたいときにあわせてどうぞ。
関連するUI事例
flexレイアウトやテーブルのはみ出し制御を、実際に動くコードで確認できる事例です。