HOME / BLOG
BLOG

Flexboxで要素が縮まない原因5選

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: 300pxflex: 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埋め込み用エリア

Flexboxで要素が縮まない原因を確認するデモ
ここにCodePenのEmbedコードを貼り付けます。Pen作成後、このブロックと埋め込みタグを差し替えてください。

CodePenでデモを作る場合は、上のindex.htmlをHTMLパネルへ、bad.cssまたはgood.cssをCSSパネルへ貼り付けてください。長いタイトルを入れたカードを横並びにすると、min-width: 0の有無による違いが確認しやすいです。

まとめ

Flexboxで要素が縮まないときは、flex-shrinkだけを見るのではなく、min-width、固定幅、長い文字列、画像、nowrapを順番に確認するのが近道です。特にmin-width: 0は、カードUIや記事一覧でかなり効きます。

参考資料