Flexboxは、要素の横並びや複雑な配置を直感的かつ柔軟に組むことができる、Web制作に不可欠なレイアウト手法です。
本記事では、プロパティの使い方、等幅カラムの実装、実務で頻発する「効かない」「画像が伸びる」といったトラブルの解決策まで解説します。
また、CSSに関するカテゴリーページから学びたい内容を決めたい人は、以下のCSSページをご確認ください。
Flexboxとは:仕組みと使い方
Webデザインやコーディングを学ぶ上で、避けて通れないのが「Flexbox」です。
Flexboxと検索して、意味や概念を調べようとしている方も多いでしょう。
一言で言えば、Flexboxとは「複雑なレイアウトを少ないコードで直感的かつ柔軟に組むflexプロパティの集合体です。
ここでは、Web制作におけるflexレイアウトの基本を解説します。
displayプロパティの種類を詳しく知りたい人は「【html&css】displayの種類は?flexやinline-blockの違い」を一読ください。
display: flexの指定と横並び・縦並び- FlexboxとGrid・floatの違いと使い分け
display: flexの指定と横並び・縦並び
Flexboxを使うには、アイテムを包んでいる「親要素」に対してdisplay: flex;を指定することです。
この1行を書くだけで、子要素は横並びに整列します。
並びの方向をコントロールするのがflex-directionプロパティです。
デフォルトは横並びのrowですが、スマートフォンの画面などで縦に並べ替えたい場合はcolumnに変更します。
HTMLコード表示
<div class="flex-demo-wrapper">
<div class="flex-demo-title">横並び (flex-direction: row) ※デフォルト</div>
<div class="flex-container-row">
<div class="flex-item">Item 1</div>
<div class="flex-item">Item 2</div>
<div class="flex-item">Item 3</div>
</div>
<div class="flex-demo-title">縦並び (flex-direction: column)</div>
<div class="flex-container-column">
<div class="flex-item">Item 1</div>
<div class="flex-item">Item 2</div>
<div class="flex-item">Item 3</div>
</div>
</div>CSSコード表示
/* 装飾用のベーススタイル */
.flex-demo-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
font-family: sans-serif;
}
.flex-demo-title {
font-size: 16px;
color: #333;
margin-bottom: 10px;
}
.flex-item {
background-color: #007bff;
color: #fff;
padding: 15px 20px;
border-radius: 4px;
font-weight: bold;
text-align: center;
}
/* 💡 ここからがFlexboxの指定 */
/* 横並びの親要素 */
.flex-container-row {
display: flex;
flex-direction: row; /* ※省略しても自動的にrowになります */
gap: 10px; /* アイテム間の余白 */
background-color: #e9ecef;
padding: 15px;
border-radius: 8px;
margin-bottom: 30px;
}
/* 縦並びの親要素 */
.flex-container-column {
display: flex;
flex-direction: column; /* 縦に並べる指定 */
gap: 10px;
background-color: #e9ecef;
padding: 15px;
border-radius: 8px;
}FlexboxとGrid・floatの違いと使い分け
CSSのレイアウト手法には歴史と種類があり、「flexとflexbox」で悩む方もいますが、これらは全く同じものを指しています。
実務で悩むのは「flexとblock」、「flexとgrid」、「flexとfloat」といった別手法との使い分けです。
- floatとの違い:
横並びの主流だったfloatは、画像にテキストを回り込ませる機能です。
高さの計算が狂うなどバグの温床になるため、レイアウト目的でfloatを使うのは非推奨です。 - Gridとの違い
Flexboxは「1次元(横一列、または縦一列)」のレイアウトに特化しています。
Gridは「2次元(縦横のマス目)」のレイアウトに特化しています。
Web Developer / Designer
HTMLコード表示
<div class="flex-card-wrapper">
<div class="profile-card">
<div class="profile-icon">👤</div>
<div class="profile-info">
<div class="profile-name">Sugi</div>
<p class="profile-job">Web Developer / Designer</p>
</div>
<button class="profile-btn">Follow</button>
</div>
</div>CSSコード表示
.flex-card-wrapper {
padding: 20px;
background-color: #f1f3f5;
border-radius: 8px;
}
/* 💡 Flexboxを使ってカード内の要素を横一列に並べ、縦の中央を揃える */
.profile-card {
display: flex;
flex-direction: row;
align-items: center; /* 縦方向の中央揃え(floatでは超困難だった処理) */
background-color: #ffffff;
padding: 20px;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
}
.profile-icon {
font-size: 40px;
background-color: #e9ecef;
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
margin-right: 20px;
}
/* 💡 flex: 1; を指定して、余った幅をすべてテキスト部分に割り当てる */
.profile-info {
flex: 1;
}
.profile-name {
margin: 0;
font-size: 18px;
color: #212529;
}
.profile-job {
margin: 5px 0 0 0;
font-size: 14px;
color: #868e96;
}
.profile-btn {
background-color: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 20px;
font-weight: bold;
cursor: pointer;
margin-left: 20px; /* テキストとボタンの隙間 */
}Gridの使い方を詳しく知りたい人は「【CSS】Gridの使い方:Flexboxとの違いやレスポンシブ」を一読ください。
要素の配置:上下中央・右寄せ・均等揃え
Flexboxの特徴は、複雑な計算やハックが必要だった要素の配置を直感的な制御で実施できる点にあります。
特に、横方向の配置を決めるjustify-content、縦方向の配置を決めるalign-itemsはFlexboxを理解する上で重要な2大プロパティです。
ここでは、実務で頻出する上下左右の配置テクニックなどを解説します。
justify-contentで横方向の配置align-itemsで縦方向の配置gapプロパティでアイテム間の余白を指定- 特定の要素だけ配置を変える
justify-contentで横方向の配置
親要素の中で、子要素を横方向にどう並べるかを決定するのがjustify-contentです。
実務で特に使うのは以下の3つです。
center: 要素を中央に集めるflex-end: 要素を右端に寄せるspace-between: 最初と最後の要素を両端にピタッとくっつけ、残りの要素を均等に配置する
1. 中央寄せ (center)
2. 右寄せ (flex-end)
3. 両端揃え (space-between)
HTMLコード表示
<div class="justify-demo-wrapper">
<p class="demo-caption">1. 中央寄せ (center)</p>
<div class="flex-justify-center">
<div class="j-item">Item 1</div>
<div class="j-item">Item 2</div>
</div>
<p class="demo-caption">2. 右寄せ (flex-end)</p>
<div class="flex-justify-right">
<div class="j-item">Item 1</div>
<div class="j-item">Item 2</div>
</div>
<p class="demo-caption">3. 両端揃え (space-between)</p>
<div class="flex-justify-between">
<div class="j-item">Logo</div>
<div class="j-item">Menu</div>
<div class="j-item">Login</div>
</div>
</div>CSSコード表示
.justify-demo-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}
.demo-caption {
font-size: 14px;
font-weight: bold;
margin-bottom: 5px;
color: #333;
}
.j-item {
background-color: #0d6efd;
color: white;
padding: 10px 20px;
border-radius: 4px;
font-weight: bold;
}
/* 💡 中央寄せ */
.flex-justify-center {
display: flex;
justify-content: center; /* 横方向の中央 */
gap: 10px;
background-color: #e9ecef;
padding: 10px;
margin-bottom: 20px;
}
/* 💡 右寄せ */
.flex-justify-right {
display: flex;
justify-content: flex-end; /* 横方向の右端 */
gap: 10px;
background-color: #e9ecef;
padding: 10px;
margin-bottom: 20px;
}
/* 💡 両端揃え(ヘッダーで頻出) */
.flex-justify-between {
display: flex;
justify-content: space-between; /* 両端に配置して間を均等に */
background-color: #e9ecef;
padding: 10px;
}align-itemsで縦方向の配置
横方向の配置ができたら、次は縦方向(交差軸方向)の配置です。
これを担うのがalign-itemsです。
覚えておくべき値は以下の2つです。
center
アイテムの縦の上下中央を揃える。
アイコンとテキストを横並びにする際などに必須です。stretch(デフォルト値)
親要素の高さまたは一番背の高いアイテムに合わせて、他のアイテムも縦に伸びる。
カードレイアウトの高さを揃える時に活躍します。
1. 高さ揃え (stretch) ※デフォルト
このアイテムの高さに合わせて、
左のアイテムも自動的に縦に伸びます。
2. 上下中央揃え (center)
HTMLコード表示
<div class="align-demo-wrapper">
<p class="demo-caption">1. 高さ揃え (stretch) ※デフォルト</p>
<div class="flex-align-stretch">
<div class="a-item">短いテキスト</div>
<div class="a-item">
長いテキストが入ったカード。<br>
このアイテムの高さに合わせて、<br>
左のアイテムも自動的に縦に伸びます。
</div>
</div>
<p class="demo-caption">2. 上下中央揃え (center)</p>
<div class="flex-align-center">
<div class="icon">🔔</div>
<div class="text">お知らせ(アイコンと文字の縦中央がピタッと揃います)</div>
</div>
</div>CSSコード表示
.align-demo-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}
.a-item {
background-color: #198754;
color: white;
padding: 15px;
border-radius: 4px;
font-size: 14px;
}
/* 💡 高さ揃え(stretch) */
.flex-align-stretch {
display: flex;
align-items: stretch; /* 一番高い要素に合わせて伸びる */
gap: 15px;
background-color: #e9ecef;
padding: 15px;
margin-bottom: 20px;
}
/* 💡 上下中央揃え(center) */
.flex-align-center {
display: flex;
align-items: center; /* 縦方向の中央を合わせる */
background-color: #e9ecef;
padding: 15px;
border-radius: 8px;
}
.icon {
font-size: 30px;
margin-right: 15px;
}
.text {
font-weight: bold;
color: #333;
}gapプロパティでアイテム間の余白を指定
Flexboxの機能として、アイテム間の隙間を指定するgapプロパティがあります。
従来は、アイテム間の「間隔」を作るためにmargin-rightを指定し、最後のアイテムだけmargin-right: 0;で打ち消す…という面倒な作業が必要でしたが、gap: 20px;と一行書くだけで解決できます。
gapはあくまで「アイテムとアイテムの『間』」にだけ余白を作ります。
コンテナの外側とアイテムの間に余白が欲しい場合は、コンテナ自身にpaddingを指定する必要があります。
gapによる余白(右端に不要な余白ができない)
HTMLコード表示
<div class="gap-demo-wrapper">
<p class="demo-caption">gapによる余白(右端に不要な余白ができない)</p>
<div class="flex-gap-container">
<div class="g-btn">Button 1</div>
<div class="g-btn">Button 2</div>
<div class="g-btn">Button 3</div>
</div>
</div>CSSコード表示
.gap-demo-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}
/* 💡 gapを使った余白の指定 */
.flex-gap-container {
display: flex;
gap: 20px; /* アイテム間にのみ20pxの隙間を作る */
background-color: #e9ecef;
padding: 15px; /* 外側の余白はpaddingでとる */
border-radius: 8px;
}
.g-btn {
background-color: #6c757d;
color: white;
padding: 10px 20px;
border-radius: 4px;
/* ❌ margin-right: 20px; のような古い指定はもう不要です */
}特定の要素だけ配置を変える
Flexboxを使っていると、「基本は左寄せにしたいけど、一番最後のボタンだけ右端に置きたい」、「このアイテムだけ縦の配置を下揃えにしたい」といった例外処理が必要になる場面があります。
縦方向(交差軸)の例外処理には子要素に直接指定するalign-selfを使いますが、横方向の「右寄せ」に関してはjustify-selfではなく別のテクニックを使います。
ちなみに、Gridにはjustify-selfというプロパティがありますが、Flexboxにはjustify-selfは存在しません。
横方向で「特定の要素だけ右に押しやる」ためのプロパティは、margin-left: auto;です。
ヘッダーのよくあるレイアウト(ログインボタンだけ右寄せ)
HTMLコード表示
<div class="self-demo-wrapper">
<p class="demo-caption">ヘッダーのよくあるレイアウト(ログインボタンだけ右寄せ)</p>
<header class="flex-header">
<div class="h-logo">SITE LOGO</div>
<div class="h-nav">Home</div>
<div class="h-nav">About</div>
<div class="h-nav">Service</div>
<div class="h-login">Login</div>
</header>
</div>CSSコード表示
.gap-demo-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}
/* 💡 gapを使った余白の指定 */
.flex-gap-container {
display: flex;
gap: 20px; /* アイテム間にのみ20pxの隙間を作る */
background-color: #e9ecef;
padding: 15px; /* 外側の余白はpaddingでとる */
border-radius: 8px;
}
.g-btn {
background-color: #6c757d;
color: white;
padding: 10px 20px;
border-radius: 4p.self-demo-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}
.flex-header {
display: flex;
align-items: center; /* 縦中央揃え */
gap: 20px; /* 全体の基本の間隔 */
background-color: #ffffff;
padding: 15px 25px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.h-logo {
font-weight: bold;
font-size: 18px;
color: #007bff;
margin-right: 10px; /* ロゴの右側だけ少し広めに */
}
.h-nav {
color: #555;
font-size: 14px;
cursor: pointer;
}
/* 💡 左側の余白を限界までとって、自身を右端に押しやる1行 */
.h-login {
background-color: #28a745;
color: white;
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
margin-left: auto; /* ★これが右寄せ★ */
}要素のサイズと伸縮(flex・grow・shrink)
Flexboxの配置(横並び・縦並び・中央寄せなど)を理解したら、「アイテムのサイズと伸縮」の制御です。
Flexboxは、画面幅や親要素のサイズに合わせて、子要素のサイズを自動で伸ばしたり縮めたりできる独自のパラメーターを持っています。
ここでは、実務で必須となる伸縮のルールについて解説します。
- ショートハンド
flex: 1の意味と書き方 - 余白を埋めると縮みを防ぐ
- 等幅・比率で分割する
ショートハンドflex: 1の意味と書き方
実務のコードを見ていると、子要素にflex: 1;とだけ書かれているのを目にするはずです。
これは以下の3つのプロパティを1行でまとめたショートハンド(一括指定)です。
flex-grow(伸びる割合)flex-shrink(縮む割合)flex-basis(ベースとなる基準幅)
flex: 1;と書いた場合、ブラウザ内部では自動的にflex: 1 1 0%;として解釈されます。
つまり、「他の要素が占有した後の残りスペースを全部自分のものとして広がる」という指定になります。
「中身に関係なくキッチリ等分したい」場合はflex: 1;を使い、「中身のテキスト量に合わせて自然な幅にしたい」場合はflex: auto;を使い分けるのがよいです。
また、伸縮させたくない固定幅の要素にはflex: none;を指定して保護します。
※左のアイコンと右のボタンは幅が固定され、真ん中の入力欄(flex: 1)が残りの余白をすべて吸収して伸びます。
.search-container {
display: flex;
align-items: center;
gap: 10px;
}
/* 💡 固定したい要素(アイコンやボタン) */
.icon, .submit-btn {
flex: none; /* 💡 絶対に伸び縮みさせない(0 0 auto) */
}
/* 💡 残りをすべて埋める要素 */
.input-area {
flex: 1; /* 💡 余白をすべて自分のものにする */
}
HTMLコード表示
<div class="flex-size-sec1-wrapper">
<div class="flex-size-sec1-box">
<p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
※左のアイコンと右のボタンは幅が固定され、真ん中の入力欄(flex: 1)が残りの余白をすべて吸収して伸びます。
</p>
<div class="f-search-container">
<div class="f-icon">🔍</div>
<div class="f-input-area">
検索キーワードを入力 (flex: 1)
</div>
<button class="f-submit-btn">検索</button>
</div>
</div>
<div class="flex-size-sec1-code">
/* 💡 親要素(Flexコンテナ) */<br>
<span class="hl-blue">.search-container</span> {<br>
<span class="hl-green">display: flex;</span><br>
<span class="hl-green">align-items: center;</span><br>
<span class="hl-green">gap: 10px;</span><br>
}<br><br>
/* 💡 固定したい要素(アイコンやボタン) */<br>
<span class="hl-blue">.icon, .submit-btn</span> {<br>
<span class="hl-red">flex: none;</span> /* 💡 絶対に伸び縮みさせない(0 0 auto) */<br>
}<br><br>
/* 💡 残りをすべて埋める要素 */<br>
<span class="hl-blue">.input-area</span> {<br>
<span class="hl-red">flex: 1;</span> /* 💡 余白をすべて自分のものにする */<br>
}
</div>
</div>CSSコード表示
.flex-size-sec1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
}
.flex-size-sec1-box {
background-color: #ffffff;
padding: 25px;
border-radius: 4px;
border: 1px solid #ced4da;
margin-bottom: 20px;
}
/* 親要素 */
.f-search-container {
display: flex;
align-items: center;
gap: 10px;
background-color: #e9ecef;
padding: 10px;
border-radius: 50px;
}
/* 固定要素 */
.f-icon {
flex: none; /* 0 0 auto と同義 */
font-size: 20px;
padding-left: 10px;
}
.f-submit-btn {
flex: none; /* 絶対に縮まない・伸びない */
background-color: #0d6efd;
color: white;
border: none;
padding: 10px 20px;
border-radius: 50px;
font-weight: bold;
cursor: pointer;
}
/* 残りを埋める要素 */
.f-input-area {
flex: 1; /* 余白をすべて埋める */
background-color: white;
padding: 10px 15px;
border-radius: 4px;
border: 1px solid #ced4da;
color: #6c757d;
font-size: 14px;
}
.flex-size-sec1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
border-radius: 4px;
font-family: monospace;
font-size: 13px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hl-blue { color: #61afef; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }余白を埋めると縮みを防ぐ
ショートハンドを分解して、個別に制御するプロパティが「grow」「shrink」「basis」です。
flex-grow: 余白があった場合、指定した数値の割合で要素を伸ばします。flex-shrink: 画面が狭くなり要素が入りきらなくなった場合、指定した数値の割合で要素を縮めます。flex-basis: 要素の「理想的な基本幅」を指定します。
プロフィール画像の丸いアイコンや「送信」といった変形してほしくない固定サイズのボタンには、flex-shrink: 0;を単独で指定してください。
どんなに画面が狭くなっても要素が潰れるというバグを防げます。
※画面幅が狭い状況を疑似的に再現しています。「縮むのを許可(デフォルト)」したアイコンは楕円形に潰れますが、「縮むのを禁止(flex-shrink: 0)」したアイコンは真円を保ちます。
テキストが長すぎると、左のアイコンがスペースを奪われて強制的に縮まされ、楕円形に潰れてしまいます。
flex-shrink: 0; を指定することで、どんなにスペースが狭くても丸い形状を完璧に維持します。
.avatar-wrong {
width: 50px;
height: 50px;
border-radius: 50%;
/* スペースが足りないと width指定を無視して勝手に縮む */
}
/* ⭕️ プロの鉄則:絶対に縮ませない */
.avatar-correct {
width: 50px;
height: 50px;
border-radius: 50%;
flex-shrink: 0; /* 💡 縮むことを禁止する魔法の1行 */
}
HTMLコード表示
<div class="flex-size-sec2-wrapper">
<div class="flex-size-sec2-box">
<p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
※画面幅が狭い状況を疑似的に再現しています。「縮むのを許可(デフォルト)」したアイコンは楕円形に潰れますが、「縮むのを禁止(flex-shrink: 0)」したアイコンは真円を保ちます。
</p>
<div class="f-profile-card f-narrow">
<div class="f-avatar-wrong">頭</div>
<div class="f-text">
<strong style="color:#dc3545;">❌ 失敗 (潰れる)</strong><br>
テキストが長すぎると、左のアイコンがスペースを奪われて強制的に縮まされ、楕円形に潰れてしまいます。
</div>
</div>
<div class="f-profile-card f-narrow">
<div class="f-avatar-correct">頭</div>
<div class="f-text">
<strong style="color:#198754;">⭕️ 正解 (形をキープ)</strong><br>
flex-shrink: 0; を指定することで、どんなにスペースが狭くても丸い形状を完璧に維持します。
</div>
</div>
</div>
<div class="flex-size-sec1-code">
/* ❌ 初心者のミス:何も指定しない(デフォルトは shrink: 1) */<br>
<span class="hl-blue">.avatar-wrong</span> {<br>
<span class="hl-green">width: 50px;</span><br>
<span class="hl-green">height: 50px;</span><br>
<span class="hl-green">border-radius: 50%;</span><br>
<span class="hl-comment">/* スペースが足りないと width指定を無視して勝手に縮む */</span><br>
}<br><br>
/* ⭕️ プロの鉄則:絶対に縮ませない */<br>
<span class="hl-blue">.avatar-correct</span> {<br>
<span class="hl-green">width: 50px;</span><br>
<span class="hl-green">height: 50px;</span><br>
<span class="hl-green">border-radius: 50%;</span><br>
<span class="hl-red">flex-shrink: 0;</span> /* 💡 縮むことを禁止する魔法の1行 */<br>
}
</div>
</div>CSSコード表示
.flex-size-sec2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
}
.flex-size-sec2-box {
background-color: #ffffff;
padding: 25px;
border-radius: 4px;
border: 1px solid #ced4da;
margin-bottom: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
/* スマホのような狭い幅を再現 */
.f-narrow {
width: 250px;
}
.f-profile-card {
display: flex;
align-items: flex-start;
gap: 15px;
background-color: #f8f9fa;
padding: 15px;
border-radius: 8px;
border: 1px solid #ced4da;
margin-bottom: 15px;
}
/* ❌ 失敗:縮むアイコン */
.f-avatar-wrong {
width: 60px;
height: 60px;
background-color: #dc3545;
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-weight: bold;
/* flex-shrink を指定していないため、テキストに押されて楕円に潰れる */
}
/* ⭕️ 正解:縮まないアイコン */
.f-avatar-correct {
width: 60px;
height: 60px;
background-color: #198754;
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-weight: bold;
/* 💡 潰れるのを防ぐ */
flex-shrink: 0;
}
.f-text {
font-size: 13px;
color: #333;
line-height: 1.5;
}
.hl-comment { color: #6c757d; font-style: italic; }等幅・比率で分割する
「要素を完全に同じ幅で並べたい」、あるいは「左を1、右を2の割合で分けたい」というケースは実務で多発します。
2等分や3等分を実現するには、対象の子要素に同じ比率の数値を指定します。
隙間を含めた上で等幅(50%や33.3%)や比率分割を作る場合は、widthを手計算するのではなく、子要素にflex: 1;を指定してください。
flex: 1はgapの隙間分を自動的に差し引いてから残りのスペースを等分するため、レイアウト崩れが起きません。
※gapで隙間を空けても、アイテムが親枠をはみ出すことなく美しく均等・比率で分割されます。
3等分(1 : 1 : 1)
比率分割(1 : 2)
.ratio-container {
display: flex;
gap: 20px;
}
/* 💡 完全な等分(1:1:1) */
.equal-item {
flex: 1; /* 💡 全員に1を指定すれば均等に分かれる */
}
/* 💡 異なる比率の分割(1:2) */
.ratio-1 {
flex: 1;
}
.ratio-2 {
flex: 2; /* 💡 左の2倍の幅になる */
}
HTMLコード表示
<div class="flex-size-sec3-wrapper">
<div class="flex-size-sec3-box">
<p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
※gapで隙間を空けても、アイテムが親枠をはみ出すことなく美しく均等・比率で分割されます。
</p>
<p style="font-size:13px; font-weight:bold; margin-bottom:5px;">3等分(1 : 1 : 1)</p>
<div class="f-ratio-container">
<div class="f-equal-item">1 (flex: 1)</div>
<div class="f-equal-item">1 (flex: 1)</div>
<div class="f-equal-item">1 (flex: 1)</div>
</div>
<p style="font-size:13px; font-weight:bold; margin-top:20px; margin-bottom:5px;">比率分割(1 : 2)</p>
<div class="f-ratio-container">
<div class="f-ratio-1">1 (flex: 1)</div>
<div class="f-ratio-2">2 (flex: 2)</div>
</div>
</div>
<div class="flex-size-sec1-code">
/* 💡 親要素(gapで隙間を空ける) */<br>
<span class="hl-blue">.ratio-container</span> {<br>
<span class="hl-green">display: flex;</span><br>
<span class="hl-green">gap: 20px;</span><br>
}<br><br>
/* 💡 完全な等分(1:1:1) */<br>
<span class="hl-blue">.equal-item</span> {<br>
<span class="hl-red">flex: 1;</span> /* 💡 全員に1を指定すれば均等に分かれる */<br>
}<br><br>
/* 💡 異なる比率の分割(1:2) */<br>
<span class="hl-blue">.ratio-1</span> {<br>
<span class="hl-red">flex: 1;</span><br>
}<br>
<span class="hl-blue">.ratio-2</span> {<br>
<span class="hl-red">flex: 2;</span> /* 💡 左の2倍の幅になる */<br>
}
</div>
</div>CSSコード表示
.flex-size-sec3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
}
.flex-size-sec3-box {
background-color: #ffffff;
padding: 25px;
border-radius: 4px;
border: 1px solid #ced4da;
margin-bottom: 20px;
}
.f-ratio-container {
display: flex;
gap: 20px; /* ここを大きくしても子要素が自動計算で縮んでくれる */
background-color: #e9ecef;
padding: 15px;
border-radius: 8px;
}
/* 1:1:1 のアイテム */
.f-equal-item {
flex: 1;
background-color: #0d6efd;
color: white;
padding: 20px 10px;
text-align: center;
font-weight: bold;
border-radius: 4px;
}
/* 1:2 のアイテム */
.f-ratio-1 {
flex: 1;
background-color: #6c757d;
color: white;
padding: 20px 10px;
text-align: center;
font-weight: bold;
border-radius: 4px;
}
.f-ratio-2 {
flex: 2; /* 隣の2倍の領域をもらう */
background-color: #198754;
color: white;
padding: 20px 10px;
text-align: center;
font-weight: bold;
border-radius: 4px;
}折り返し(wrap)と複数行・カラムレイアウト
Flexboxは初期設定のまま使うと、中に入れた要素が増えても「1行に収めようとする」という性質を持ちます。
ここでは、要素を「新しい行」へ押し出して複数行のレイアウトを作るプロパティ、実務で頻出する「2列・3列」などのグリッド型カラムレイアウトをFlexboxで構築する方法を解説します。
flex-wrapで要素を改行・折り返しさせる- 2列・3列・4列などカラム数の固定と強制改行
flex-wrapで要素を改行・折り返しさせる
Flexboxのコンテナ内にある要素を折り返しさせるプロパティがflex-wrapです。
デフォルト値は折り返さないnowrapに設定されているため、wrapに変更することで、要素が親枠の幅を超えたタイミングで下の行へ改行されます。
カード一覧やギャラリーなど、アイテムの数が親要素の幅をはみ出す可能性があるコンポーネントを作る際は、親要素にdisplay: flex;とflex-wrap: wrap;はセットで書く癖をつけてください。
これが意図しない要素の「潰れ」を防ぐ防御策です。
❌ 失敗:デフォルト(nowrap)は幅指定を無視して潰れる
⭕️ 正解:wrapを指定すると、元の幅を保って改行される
HTMLコード表示
<div class="wrap-demo-wrapper">
<p class="demo-caption">❌ 失敗:デフォルト(nowrap)は幅指定を無視して潰れる</p>
<div class="flex-container-nowrap">
<div class="w-item">150px</div>
<div class="w-item">150px</div>
<div class="w-item">150px</div>
<div class="w-item">150px</div>
<div class="w-item">150px</div>
</div>
<p class="demo-caption" style="margin-top:20px;">⭕️ 正解:wrapを指定すると、元の幅を保って改行される</p>
<div class="flex-container-wrap">
<div class="w-item">150px</div>
<div class="w-item">150px</div>
<div class="w-item">150px</div>
<div class="w-item">150px</div>
<div class="w-item">150px</div>
</div>
</div>CSSコード表示
.wrap-demo-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
/* 親要素の幅をデモ用に固定して、はみ出させる状況を作る */
max-width: 500px;
margin: 0 auto;
}
.demo-caption {
font-size: 13px;
font-weight: bold;
margin-bottom: 5px;
color: #333;
}
.w-item {
background-color: #0d6efd;
color: white;
/* 💡 全ての要素に 150px を指定 */
width: 150px;
padding: 15px 0;
text-align: center;
font-weight: bold;
border-radius: 4px;
}
/* ❌ nowrap(デフォルト)の親要素 */
.flex-container-nowrap {
display: flex;
/* flex-wrap: nowrap; が隠れている状態 */
gap: 10px;
background-color: #e9ecef;
padding: 10px;
border: 1px solid #dc3545;
}
/* ⭕️ wrap を指定した親要素 */
.flex-container-wrap {
display: flex;
flex-wrap: wrap; /* 💡 はみ出たら改行(折り返し)する1行 */
gap: 10px;
background-color: #e9ecef;
padding: 10px;
border: 1px solid #198754;
}2列・3列・4列などカラム数の固定と強制改行
Flexboxを使って、要素を「横並び2列」や「同じ幅の3列」、「1行につき4個」といったグリッド状のレイアウトを作ることは実務で多発します。
折り返しの個数を制限するには、子要素の横幅(width)をパーセント(%)でコントロールする必要があります。
Flexboxとgapを組み合わせてカラム数(2列や3列)を作る場合、子要素のwidthにはcalc()関数を使って隙間の分を計算から引き算してください。
- 2列の計算式:
width: calc((100% - gapの幅 * 1) / 2); - 3列の計算式:
width: calc((100% - gapの幅 * 2) / 3);
計算式(スニペット)を辞書登録しておけば、どんな余白でも崩れないカラムレイアウトが構築できます。
2列レイアウト(隙間20px)
3列レイアウト(隙間15px)
HTMLコード表示
<div class="column-demo-wrapper">
<p class="demo-caption">2列レイアウト(隙間20px)</p>
<div class="flex-wrap-container">
<div class="col-2-item">Item 1</div>
<div class="col-2-item">Item 2</div>
<div class="col-2-item">Item 3</div>
<div class="col-2-item">Item 4</div>
</div>
<p class="demo-caption" style="margin-top:20px;">3列レイアウト(隙間15px)</p>
<div class="flex-wrap-container-3">
<div class="col-3-item">Item 1</div>
<div class="col-3-item">Item 2</div>
<div class="col-3-item">Item 3</div>
<div class="col-3-item">Item 4</div>
<div class="col-3-item">Item 5</div>
</div>
</div>CSSコード表示
.column-demo-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}
.demo-caption {
font-size: 14px;
font-weight: bold;
margin-bottom: 5px;
color: #333;
}
/* --- 💡 2列レイアウトの実装 --- */
.flex-wrap-container {
display: flex;
flex-wrap: wrap; /* 必須:折り返し許可 */
gap: 20px; /* アイテム間の隙間 */
background-color: #e9ecef;
padding: 15px;
border-radius: 4px;
}
.col-2-item {
background-color: #198754;
color: white;
padding: 20px 0;
text-align: center;
border-radius: 4px;
/* 💡 calc()を使って隙間分を引く */
/* (100% - 隙間20pxが1箇所) ÷ 2個 */
width: calc((100% - 20px) / 2);
}
/* --- 💡 3列レイアウトの実装 --- */
.flex-wrap-container-3 {
display: flex;
flex-wrap: wrap; /* 必須:折り返し許可 */
gap: 15px; /* アイテム間の隙間 */
background-color: #e9ecef;
padding: 15px;
border-radius: 4px;
}
.col-3-item {
background-color: #fd7e14;
color: white;
padding: 20px 0;
text-align: center;
border-radius: 4px;
/* 💡 calc()を使って隙間分を引く */
/* (100% - 隙間15pxが2箇所) ÷ 3個 */
width: calc((100% - 30px) / 3);
}効かない・崩れる!Flexboxのトラブル解決
Flexboxは強力なレイアウト手法ですが、独自のルールがあるため、「CSSが効かない」というトラブルに遭遇します。
思い通りに動かない時、実は「コードが間違っている」のではなく、「Flexboxの仕様上、その状態では動かない」ことがほとんどです。
ここでは、実務で頻出する「横並びにならない」「画像が伸びる」といった2大トラブルの原因と解決策を解説します。
- 横並びにならない・
justify-contentが効かない - 画像が伸びる・高さが勝手に揃う問題の解消
横並びにならない・justify-contentが効かない
「横並びにならない」という相談の9割は、初歩的な指定ミスです。
display: flex;は「親要素」に指定するものであり、並べたい子要素に直接指定しても効果はありません。
また、「中央寄せや右寄せが効かない」というトラブルも多いです。
レイアウトが効かない時は、一時的にborder: 1px solid red;などを親要素と子要素に指定して目に見えない「箱のサイズ」を可視化してください。
余白がないと気づけば、親要素にwidth: 100%;を足すなどの解決策が見つかります。
❌ 失敗:親の幅が足りなくて、中央寄せ(center)が効かない
⭕️ 正解:親に幅を持たせることで、中央寄せが機能する
HTMLコード表示
<div class="trouble-sec1-wrapper">
<p class="demo-caption">❌ 失敗:親の幅が足りなくて、中央寄せ(center)が効かない</p>
<div class="t-flex-wrong">
<div class="t-item">Item 1</div>
<div class="t-item">Item 2</div>
</div>
<p class="demo-caption" style="margin-top:20px;">⭕️ 正解:親に幅を持たせることで、中央寄せが機能する</p>
<div class="t-flex-correct">
<div class="t-item">Item 1</div>
<div class="t-item">Item 2</div>
</div>
</div>CSSコード表示
.trouble-sec1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}
.demo-caption {
font-size: 13px;
font-weight: bold;
margin-bottom: 5px;
color: #333;
}
.t-item {
background-color: #0d6efd;
color: white;
padding: 10px 20px;
border-radius: 4px;
font-weight: bold;
}
/* ❌ 失敗例(インライン要素などにflexをかけてしまったような状態を再現) */
.t-flex-wrong {
display: flex;
justify-content: center; /* 💡 効かない! */
gap: 10px;
background-color: #f8d7da; /* 背景色で幅がないことを可視化 */
border: 2px dashed #dc3545;
/* 親要素が子要素ぴったりに縮んでいるため、寄せるスペースがない */
width: max-content;
}
/* ⭕️ 成功例 */
.t-flex-correct {
display: flex;
justify-content: center; /* 💡 綺麗に中央に寄る! */
gap: 10px;
background-color: #d1e7dd; /* 背景色で幅があることを可視化 */
border: 2px dashed #198754;
/* 💡 幅を100%確保することで、寄せるための余白が生まれる */
width: 100%;
padding: 10px;
}画像が伸びる・高さが勝手に揃う問題の解消
Flexboxを使って、左に画像、右にテキストを配置したカードレイアウトを作った際、「画像伸びる」という現象に遭遇することがあります。
右側のテキスト量が多いと、それに合わせて左側の写真が縦にビヨーンと不自然に伸びてしまう問題です。
画像が伸びるのを防ぐには、親要素にalign-items: flex-start;(上揃え)またはalign-items: center;(中央揃え)を明示的に指定して、高さを揃えない設定を上書きしてください。
どうしても画像だけを個別に直したい場合は、画像自身にalign-self: flex-start;を指定して親のstretchルールから抜け出すか、サイズを固定したい場合はflex: none;を指定して伸縮から保護するのがよいです。
❌ 失敗:デフォルト(stretch)のままだと画像が縦に伸びる
この文章の高さが全体の基準になります。
デフォルトでは高さが揃うため、
左の「画像」が縦に引っ張られます。
⭕️ 正解:align-items: flex-start; で伸びを防ぐ
指定したことで、それぞれの要素が
本来の高さのまま上揃えになります。
もう画像がビヨーンと伸びることはありません。
HTMLコード表示
<div class="trouble-sec2-wrapper">
<p class="demo-caption">❌ 失敗:デフォルト(stretch)のままだと画像が縦に伸びる</p>
<div class="t-card-wrong">
<div class="t-image-fake">画像</div>
<div class="t-text">
右側のテキスト量が多いため、<br>
この文章の高さが全体の基準になります。<br>
デフォルトでは高さが揃うため、<br>
左の「画像」が縦に引っ張られます。
</div>
</div>
<p class="demo-caption" style="margin-top:20px;">⭕️ 正解:align-items: flex-start; で伸びを防ぐ</p>
<div class="t-card-correct">
<div class="t-image-fake">画像</div>
<div class="t-text">
align-items: flex-start; を<br>
指定したことで、それぞれの要素が<br>
本来の高さのまま上揃えになります。<br>
もう画像がビヨーンと伸びることはありません。
</div>
</div>
</div>CSSコード表示
.trouble-sec2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}
.demo-caption {
font-size: 13px;
font-weight: bold;
margin-bottom: 5px;
color: #333;
}
/* ❌ 失敗例 */
.t-card-wrong {
display: flex;
/* align-items: stretch; が隠れている */
gap: 15px;
background-color: #ffffff;
padding: 15px;
border: 1px solid #ced4da;
border-radius: 8px;
}
/* ⭕️ 成功例 */
.t-card-correct {
display: flex;
/* 💡 縦の伸びを解除し、本来の高さのまま上揃えにする */
align-items: flex-start;
gap: 15px;
background-color: #ffffff;
padding: 15px;
border: 1px solid #ced4da;
border-radius: 8px;
}
.t-image-fake {
background-color: #dc3545;
color: white;
width: 80px;
/* height を指定していない、もしくはautoの場合に被害に遭う */
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
border-radius: 4px;
}
.t-text {
flex: 1;
font-size: 13px;
color: #333;
line-height: 1.6;
background-color: #e9ecef;
padding: 10px;
border-radius: 4px;
}まとめ
分かりやすいようにまとめを記載します。
- 親要素に
display: flex;を指定し、子要素(アイテム)のレイアウトを制御する。 - 1次元(単一の行または列)の配置に特化しており、ページ全体の大枠を作るGridレイアウトとは適材適所で使い分ける。
- 横方向の配置は
justify-content、縦方向の配置はalign-itemsで指定する。 - アイテム間の隙間は
marginではなくgapプロパティで管理する。 - 特定のアイテムのみを右寄せしたい場合は
margin-left: auto;を使用する。 flex: 1は残りの余白を吸収して伸び、flex-shrink: 0は画面が狭くなっても要素が潰れるのを防ぐ。- 要素を折り返して複数行にする場合は
flex-wrap: wrap;を指定する。 gapを含めた2列・3列のカラムレイアウトは、width: calc()を使って隙間分を引き算する。justify-content等が効かない時は、親要素が子要素のサイズに縮んでおり「寄せる余白」がないことが多い。- 画像やボタンが縦に伸びる場合は、親要素に
align-items: flex-start;またはcenter;を指定してデフォルトのstretchを解除する。
よくある質問(FAQ)
CSSの「Flexbox」と「Grid」の違いは何ですか?
大きな違いは「次元」です。
Flexboxは「1次元(横一列、または縦一列)」の配置を得意としており、ナビゲーションメニューやカード内の要素など、局所的な部品のレイアウトに適しています。
一方、Gridは「2次元(縦横のマス目)」を同時に制御できるため、ページ全体の大枠や、ギャラリーなどの全体配置に適しています。
実務では「大枠はGridで作り、その中の細かな並びはFlexboxで作る」という組み合わせがベストプラクティスです。
display: flex;を指定したのに横並びになりません。
よくある原因は「指定する場所の間違い」です。
Flexboxは、「親要素」に指定して、その中にある「子要素」を操る仕組みです。
横並びにしたい要素自身にdisplay: flex;を記述しても効果はありません。
横並びにしたい要素たちを囲んでいる「1つ上の親タグ」に対して指定してください。
Flexboxを使って要素を「上下左右の中央寄せ」にするには?
親要素に対して以下の3行を指定するだけで、中身が完璧に中央寄せされます。
display: flex;(Flexboxを有効化)justify-content: center;(横方向の中央寄せ)align-items: center;(縦方向の中央寄せ)
※注意点として、親要素の高さが指定されておらず中身の高さ縮んでいる場合は、縦に動くスペースがないためalign-items: center;が効いていないように見えます。
親要素に高さを確保してください。
よく見かける flex: 1;とはどういう意味ですか?
「他の要素が場所を取ったあとの、残りの余白を自分のものにして広がる」という指定です。
これはflex-grow: 1、flex-shrink: 1、flex-basis: 0%を1行でまとめたショートハンド(一括指定)です。
複数の要素にflex: 1;を指定すると、中身のテキスト量に関係なく、同じ幅(1:1:1など)で均等に分割されます。
要素が増えると細長く潰れてしまいます。折り返して複数行にするには?
親要素にflex-wrap: wrap;を追加してください。
Flexboxは初期設定がflex-wrap: nowrap;(絶対に折り返さない)になっているため、アイテムが増えると画面内に収めようとして潰れます。
wrapを指定することで、親要素の幅を超えた分が下の行へ改行(折り返し)されます。

