Flexboxで横並びを作ったとき、「画面が狭いのに要素が縮まない」「テキストや画像が親からはみ出す」というトラブルはかなり多いです。原因はflex-shrinkだけではなく、min-width、固定幅、長い文字列、画像サイズなどが絡んでいることがほとんどです。
この記事では、Flexboxで要素が縮まない代表的な原因を5つに分けて、実務で使いやすい修正方法までまとめます。
Flexboxで縮む仕組み
Flexboxの子要素は、初期状態でflex-shrink: 1です。つまり、基本的には余白が足りないと縮みます。ただし、内容物の最小幅や固定幅が強い場合は、縮みたくても縮めません。
特に重要なのがmin-width: autoです。Flexアイテムは初期状態で内容物の幅を守ろうとするため、長いタイトルやURLがあると、親要素からはみ出すことがあります。
原因1:min-width:auto が効いている
一番よくある原因です。テキストを省略表示したいのに効かない、カード本文が画像を押し出す、横スクロールが出る場合は、まずmin-width: 0を疑ってください。
<article class="card">
<img
class="card__media"
src="https://images.unsplash.com/photo-1546519638-68e109498ffc?auto=format&fit=crop&w=480&q=80"
alt="バスケットボール"
>
<div class="card__body">
<p class="card__label">CSS LAYOUT</p>
<h2 class="card__title">
Flexboxで長いタイトルが入ったときに本文エリアが縮まない例
</h2>
<p class="card__text">
本文側に min-width: 0 を指定すると、カード全体を崩さずに省略表示できます。
</p>
</div>
</article>.card {
display: flex;
gap: 16px;
max-width: 560px;
padding: 16px;
border: 2px solid #111;
background: #fff;
}
.card__media {
width: 180px;
aspect-ratio: 4 / 3;
object-fit: cover;
}
.card__body {
flex: 1;
}
.card__title {
white-space: nowrap;
}この場合、本文側が長いタイトルの幅を守ろうとして、縮まずにはみ出します。修正は本文側にmin-width: 0を入れることです。
.card {
display: flex;
gap: 16px;
max-width: 560px;
padding: 16px;
border: 2px solid #111;
background: #fff;
}
.card__media {
flex: 0 0 180px;
width: 180px;
aspect-ratio: 4 / 3;
object-fit: cover;
}
.card__body {
flex: 1 1 auto;
min-width: 0;
}
.card__title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}原因2:width や flex-basis が固定されている
width: 300pxやflex: 0 0 300pxのように固定していると、要素はその幅を強く維持します。サイドバーのように意図して固定したい場合はOKですが、スマホまで同じ幅を保つと窮屈になります。
flex: 0 0 240px:縮まない固定カラムflex: 1 1 240px:240pxを基準に、必要なら縮むflex: 1 1 auto:内容と空き幅に応じて伸縮する
原因3:長いURLや英単語が折り返せない
日本語は自然に折り返せますが、URLや長い英単語は折り返し位置が少なく、親要素から突き抜けることがあります。本文エリアにはoverflow-wrap: anywhereを用意しておくと安定します。
.content {
min-width: 0;
overflow-wrap: anywhere;
}
原因4:画像やiframeに max-width がない
画像、動画、CodePen、YouTubeなどの埋め込み要素は、元の幅が大きいとFlexアイテムを押し広げます。記事本文ではmax-width: 100%を基本セットとして入れておきましょう。
.content img,
.content video,
.content iframe {
max-width: 100%;
}
原因5:nowrap を指定している
white-space: nowrapは、テキストを1行に固定する便利な指定です。ただし、親の幅が足りない場面でははみ出しの原因になります。省略表示したい場合は、親にmin-width: 0、対象テキストにoverflow: hiddenを組み合わせます。
実務で使える基本形
サイドバー付きレイアウトやカード横並びでは、以下の形をベースにすると崩れにくくなります。
.layout {
display: flex;
gap: clamp(12px, 2vw, 24px);
}
.sidebar {
flex: 0 0 clamp(220px, 24vw, 320px);
}
.main {
flex: 1 1 auto;
min-width: 0;
}
.main img,
.main video,
.main iframe {
max-width: 100%;
}
@media (max-width: 720px) {
.layout {
flex-direction: column;
}
.sidebar {
flex-basis: auto;
}
}CodePen埋め込み用エリア
CodePenでデモを作る場合は、上のindex.htmlをHTMLパネルへ、bad.cssまたはgood.cssをCSSパネルへ貼り付けてください。長いタイトルを入れたカードを横並びにすると、min-width: 0の有無による違いが確認しやすいです。
まとめ
Flexboxで要素が縮まないときは、flex-shrinkだけを見るのではなく、min-width、固定幅、長い文字列、画像、nowrapを順番に確認するのが近道です。特にmin-width: 0は、カードUIや記事一覧でかなり効きます。
