Web制作でカードデザインやカラムレイアウトを作るとき、「横並びにした要素の高さを綺麗に揃えたい」とお悩みではありませんか?「flex 高さ 揃える」と検索して調べてみても、親要素に display: flex を指定するだけで揃う場合もあれば、なぜか意図通りに揃わなかったり、縦並びやカード内のボタンの位置だけがズレてしまったりと、予期せぬ挙動にハマってしまうことも少なくありません。
Flexboxで要素の高さを揃える基本は、実はとてもシンプルです。親要素に display: flex を指定すると、デフォルトで働く align-items: stretch という仕組みによって、一番コンテンツ量が多い要素の高さに自動で引き伸ばされます。
しかし、入れ子構造(孫要素)になっている場合や、縦並び(flex-direction: column)レイアウト、あるいは画像付きカードの配置など、実装シーンによって注意すべきポイントが異なります。
本記事では、Flexboxを使って高さを綺麗に揃える基本手順から、縦並び・カード内のボタン揃え・トラブル時の解決策まで、実際のWeb制作でそのまま使えるコード例とともに詳しく解説します。
ConoHa AI Canvas|ブラウザだけでできる本格的なAI画像生成Flexboxで高さを揃える基本|横並びならdisplay: flexで揃う

Flexbox(Flexible Box Layout Module)を使用すると、横並びにした要素の高さを自動的に揃えることができます。親要素に display: flex を指定するだけで、子要素(フレックスアイテム)の高さが一番高い要素に合わせて均等に拡張されます。高さを固定ピクセルで指定する必要がなく、文字数が異なるカードやレイアウトでも柔軟に高さを揃えられるのが特徴です。
横並びの高さはalign-items: stretch(初期値)で自動的に揃う
親要素に display: flex を指定すると、その直下の子要素は「フレックスアイテム」になります。このとき、交差軸方向(横並びの場合は垂直方向)の配置を制御するプロパティ align-items の初期値は normal ですが、Flexboxのコンテキスト内では stretch(引き伸ばし)として振る舞います。
これにより、子要素に明示的な高さを指定していなくても、最も背の高い(コンテンツ量が多い)子要素の高さに合わせて、他の子要素の高さが自動的に引き伸ばされます。
以下は、高さが異なるテキストを含むカードを横並びにして、高さを自動的に揃える基本の実装例です。
<div class="card-container">
<div class="card">
<h3>スタンダードプラン</h3>
<p>基本的な機能を利用できるプランです。個人利用におすすめです。</p>
</div>
<div class="card">
<h3>プロフェッショナルプラン</h3>
<p>ビジネス向けの高度な機能と、優先サポートが付属する充実したプランです。</p>
</div>
<div class="card">
<h3>エンタープライズ</h3>
<p>大企業向けの大規模運用プラン。専任サポートがつきます。</p>
</div>
</div>
.card-container {
display: flex;
gap: 20px; /* 子要素間の余白 */
}
.card {
flex: 1; /* 幅を均等に配分 */
background-color: #f8f9fa;
border: 1px solid #dee2e6;
padding: 24px;
border-radius: 8px;
}
このコードでは、.card-container に display: flex を指定しているため、内部の .card は自動的に横並びになり、align-items: stretch の効果によってすべてのカードの高さが一番内容の多いカードに合わせて揃います。
align-itemsの値によって高さ揃えが変わる仕組み
align-items の値を変更すると、要素の高さが揃う挙動が変わり、各要素が持つ本来の高さ(コンテンツの高さ)で表示されるようになります。
align-items に指定できる主な値と、高さに対する影響は以下の通りです。
| 指定値 | プロパティの挙動 | 高さの揃え方 |
|---|---|---|
stretch (初期値) | 交差軸方向にコンテナいっぱいに引き伸ばす | すべてのアイテムの高さが一番高いものに揃う |
flex-start | 交差軸の起点側に寄せる | 各アイテムの高さは「中身のコンテンツ量」に依存し、バラバラになる |
flex-end | 交差軸の終点側に寄せる | 各アイテムの高さは「中身のコンテンツ量」に依存し、バラバラになる |
center | 交差軸の中央に寄せる | 各アイテムの高さは「中身のコンテンツ量」に依存し、バラバラになる |
もし「カードの高さを揃えたくない」「中身の高さに合わせてそれぞれ独立させたい」という場合は、親要素に align-items: flex-start を指定します。
.card-container {
display: flex;
gap: 20px;
align-items: flex-start; /* 高さを揃えず、上部揃えにする */
}
このように、Flexboxで高さを揃えたい場合は、余計な高さを固定値(height)で指定する前に、まず display: flex による stretch の効力を理解し、想定通りの挙動になっているかを確認することが重要です。
Flexboxで縦並びの高さを揃える方法

縦並び(垂直方向のレイアウト)にした要素同士の高さを揃えたり、親要素の高さに合わせて子要素を伸縮させたりする場合、横並びとは主軸と交差軸が入れ替わる点に注意が必要です。親要素の高さが確定している状態で flex: 1 や適切なプロパティを組み合わせることで、縦方向のサイズや高さを意図通りに制御できます。
flex-direction: columnではalign-itemsが横方向に作用する
親要素に flex-direction: column を指定して子要素を縦に並べた場合、Flexboxの主軸(Main Axis)は「垂直方向」、交差軸(Cross Axis)は「水平方向」に入れ替わります。
そのため、横並びのときには高さに影響していた align-items: stretch などのプロパティは、縦並びの環境では「アイテムの幅(横方向のサイズ)」を広げる方向に作用します。
縦並びにした要素全体の高さを親要素に合わせて均等に広げたい場合は、単に align-items を変更するだけでは機能しません。親要素に具体的な高さ(height や min-height)が指定されている必要があります。
flex: 1で縦方向の空きスペースを均等に分配する
縦並びのレイアウトで各子要素の高さを均等に分割・拡張したいときは、子要素に flex: 1 を指定します。
flex: 1 は、親要素の主軸方向(縦方向)の空きスペースを、指定したアイテム同士で均等に分配するためのプロパティです。これを機能させるためには、親要素(コンテナ)に明確な高さ(例: height: 300px や height: 100vh など)が設定されていることが絶対条件となります。
親要素の高さが未確定(子要素のコンテンツ量に依存する状態)の場合、余剰スペースが存在しないため、flex: 1 を指定しても高さは均等に分配されません。
以下は、親要素の高さを固定した上で、内部の縦並びアイテムの高さを均等に揃える実装例です。
<div class="vertical-container">
<div class="box">セクション 1</div>
<div class="box">セクション 2</div>
<div class="box">セクション 3</div>
</div>
.vertical-container {
display: flex;
flex-direction: column; /* 縦並びにする */
height: 300px; /* 親要素の高さが必須 */
gap: 10px;
}
.box {
flex: 1; /* 縦方向の空きスペースを均等に配分 */
background-color: #e9ecef;
border: 1px solid #ced4da;
display: flex;
align-items: center;
justify-content: center;
}
この実装では、親要素の高さ 300px からギャップ分を除いた余剰スペースが flex: 1 によって3つの .box に均等に割り振られ、それぞれの高さが自動的に揃います。
Tailwind CSSのflex-col・flex-1で同じレイアウトを作る
Tailwind CSSを使用して同様の縦並びレイアウトや高さの均等分配を実装する場合は、対応するユーティリティクラスを組み合わせて指定します。
flex-col:flex-direction: column(縦並びにする)flex-1:flex: 1 1 0%(余剰スペースを均等に配分する)h-[300px]など:親要素の高さを指定する
以下は、Tailwind CSSを用いた縦並び・高さ均等分配の実装例です。
<div class="flex flex-col h-[300px] gap-2.5">
<div class="flex-1 bg-gray-100 border border-gray-300 flex items-center justify-center">
セクション 1
</div>
<div class="flex-1 bg-gray-100 border border-gray-300 flex items-center justify-center">
セクション 2
</div>
<div class="flex-1 bg-gray-100 border border-gray-300 flex items-center justify-center">
セクション 3
</div>
</div>
Tailwind CSSでも、通常のCSSと同様に、親要素に高さを固定するクラス(h-[300px] や h-full など)を付与していなければ、子要素の flex-1 は意図した高さの均等分配を行わないため注意が必要です。
Flexboxで子要素・孫要素の高さを揃える方法

Flexboxによる高さの自動揃えは、display: flexを指定したコンテナーの「直下の子要素(フレックスアイテム)」に対してのみ直接作用します。そのため、構造が複雑なカードレイアウトや入れ子になった要素の中身まで自動的に揃うわけではありません。孫要素やカード内のボタンの位置まで綺麗に揃えるには、階層に応じた適切なFlexboxの再指定が必要です。
親要素のdisplay: flexが適用される範囲を理解する
大本の親要素に display: flex を指定した場合、高さが揃うのは「その直下にある子要素(フレックスアイテム)」の1階層目のみです。
例えば、親要素の中にカードがあり、そのカードの中にさらにラッパー要素やテキスト、ボタンなどの孫要素が含まれている構造の場合、親要素のFlexbox設定はカードの高さに対しては機能しますが、カード内部にある孫要素の間で高さを自動的に揃えることはできません。
孫要素のレイアウトや高さを制御したい場合は、カード自体をフレックスアイテムとして扱いつつ、カード内部をさらにフレックスコンテナーとして定義する必要があります。
入れ子の要素にもdisplay: flexを設定する
カードの中にあるコンテンツ(例:ヘッダー、本文、フッターボタン)の配置や高さを子孫の階層で制御したい場合は、入れ子になる要素に対して個別に display: flex を指定します。
以下は、カード自体の高さを揃えつつ、カード内部のレイアウトもFlexboxで構成する入れ子の実装例です。
<div class="card-container">
<div class="card">
<div class="card-header">プランA</div>
<div class="card-body">
<p>基本的な機能を利用できるプランです。</p>
</div>
<div class="card-footer">
<button>詳細を見る</button>
</div>
</div>
<div class="card">
<div class="card-header">プランB</div>
<div class="card-body">
<p>ビジネス向けの高度な機能と、優先サポートが付属する充実したプランです。</p>
</div>
<div class="card-footer">
<button>詳細を見る</button>
</div>
</div>
</div>
/* 1階層目:カード全体を横並びにして高さを揃える */
.card-container {
display: flex;
gap: 20px;
}
.card {
flex: 1;
display: flex;
flex-direction: column; /* 内部を縦並びにする */
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 24px;
}
カード内のテキストやボタンの位置を揃える
文字数が異なるカードを横並びにしたとき、カード全体の高さは揃っても、中の「ボタンの位置」がバラバラになってしまうことがあります。これを綺麗に下端で揃えるためには、カード自体を縦方向のFlexboxにし、本文領域に flex: 1 を指定して余剰スペースを埋める方法が効果的です。
上記のCSSに続けて、カード内の各要素を調整します。
.card-body {
flex: 1; /* 本文領域を伸縮させて高さを自動調整し、余白を埋める */
margin-bottom: 20px;
}
.card-footer {
margin-top: auto; /* 余った上部スペースを自動的に押し出し、ボタンを下端に固定する */
}
.card-footer button {
width: 100%;
padding: 12px;
background-color: #0d6efd;
color: #fff;
border: none;
border-radius: 4px;
font-weight: bold;
}
この構成では、カード内部を flex-direction: column とし、本文領域に flex: 1 を与えることで、カード内の余白を本文領域が吸収します。これにより、テキストの量が異なってカード全体の高さが広がっても、最下部のフッター(ボタン)の位置が綺麗に揃います。
画像付きカードの高さを揃える方法
画像が含まれるカードレイアウトで高さを揃える場合、「カード全体の高さ(背景や枠線)を揃えること」と「画像自体の表示領域(サイズ)を統一すること」を混同しないよう注意が必要です。
カード全体の高さは親の display: flex と align-items: stretch で揃えられますが、元画像の縦横比がバラバラな場合、画像表示エリアのサイズが崩れる原因になります。画像サイズを綺麗に統一するには、aspect-ratio や object-fit プロパティを併用します。
以下は、画像付きカードの高さを揃えつつ、画像自体の表示領域を整える実装例です。
<div class="card-container">
<div class="image-card">
<div class="card-image-wrap">
<img src="sample1.jpg" alt="サンプル画像1">
</div>
<div class="card-content">
<h3>記事タイトル1</h3>
<p>短いテキスト説明です。</p>
</div>
</div>
<div class="image-card">
<div class="card-image-wrap">
<img src="sample2.jpg" alt="サンプル画像2">
</div>
<div class="card-content">
<h3>記事タイトル2</h3>
<p>こちらはやや長いテキストが続くカードのコンテンツになります。</p>
</div>
</div>
</div>
.card-container {
display: flex;
gap: 20px;
}
.image-card {
flex: 1;
display: flex;
flex-direction: column;
border: 1px solid #dee2e6;
border-radius: 8px;
overflow: hidden;
background-color: #fff;
}
/* 画像の表示領域をアスペクト比で固定 */
.card-image-wrap {
width: 100%;
aspect-ratio: 16 / 9; /* 16:9の比率に固定 */
background-color: #e9ecef;
}
.card-image-wrap img {
width: 100%;
height: 100%;
object-fit: cover; /* 比率を維持しながら領域を埋める */
}
.card-content {
flex: 1;
padding: 20px;
}
このように、カード全体の高さはFlexboxの stretch で揃え、画像部分は aspect-ratio と object-fit: cover で表示領域を一定に保つことで、レイアウトの整った高品質なカードグリッドを実現できます。
Flexboxで高さが揃わない原因と対処法

Flexboxで横並びにしたものの「なぜか高さが揃わない」「一部の要素だけ意図しない高さになる」というトラブルは、CSSの仕様や初期値、指定したプロパティの干渉が原因で発生します。ここでは、よくある原因と具体的な対処法を順に解説します。
align-itemsやalign-selfがstretch以外になっている
親要素の align-items に stretch 以外の値(flex-start、flex-end、center など)が指定されている場合、子要素は交差軸方向いっぱいに引き伸ばされなくなります。その結果、各要素は自身のコンテンツ量に応じた個別の高さになり、高さが揃わなくなります。
対処法:
高さの一括を揃えたい場合は、親要素の align-items を stretch に設定するか(初期値のため指定を削除しても可)、特定の要素だけに影響している場合は align-self: stretch を適用して引き伸ばしを有効にします。
.card-container {
display: flex;
align-items: stretch; /* 各要素の高さを行の中で最も高いものに揃える */
}
子要素のheight・min-height・max-heightを確認する
子要素(フレックスアイテム)に対して、個別に明示的な height や min-height が設定されている場合、align-items: stretch による引き伸ばしよりも優先される、または制限がかかることがあります。
例えば、一部の子要素に height: 100px や min-height: 200px がハードコーディングされていると、他の要素のコンテンツ量が増えてもそのサイズに固定されてしまい、高さが不揃いになります。
対処法:
高さが揃わない要素のCSSを検証し、意図しない固定の height や制約となる min-height / max-height が指定されていないか確認し、必要に応じて削除または調整します。
height: 100%が効かない場合の確認ポイント
子要素の高さや内部のレイアウトに対して height: 100% を指定したにもかかわらず高さが機能しない場合、その包含ブロック(親要素)の高さが確定していないことが主な原因です。
CSSのパーセント指定による高さ(height: 100%)は、親要素に具体的な高さ(例: height: 500px や height: 100vh)が明示されている必要があります。親要素の高さが「内容に依存して自動的に決まる状態(height: auto)」の場合、100% の基準となる高さが存在しないため、ブラウザは高さを計算できなくなります。
対処法:
親要素に対して明確な高さを指定するか、Flexbox自体の stretch の仕組みを利用して高さを揃える設計に変更します。
/* 親要素の高さを基準にする場合の例 */
.parent {
display: flex;
height: 400px; /* 親の高さを明示 */
}
.child {
height: 100%; /* 親の高さ(400px)の100%として機能する */
}
flex-wrapで折り返したときの高さの違いを確認する
親要素に flex-wrap: wrap を指定してアイテムを複数行に折り返した場合、同じ行(フレックス行)の中では高さが揃いますが、異なる行の間では高さが自動的に統一されません。
例えば、1行目に背の高いカードが含まれていると1行全体の高さはその要素に合わせられますが、2行目は2行目の中で最も高い要素に合わせて個別に高さが決まるため、行ごとに全体の高さがバラバラになる現象が起きます。
対処法:
行ごとの高さのバラつきを完全に防ぎたい場合は、Flexboxではなく CSS Grid(display: grid)を使用する方が、行と列の両方でサイズを綺麗に制御しやすくなります。Flexboxで対応する場合は、各カードの内部構造やテキストの最大文字数を揃えるなどの設計上の調整が必要です。
Chrome DevToolsでFlexboxの計算結果を確認する
原因が特定できないときは、ブラウザの検証ツール(Chrome DevToolsなど)を活用して実際の計算結果を確認するのが確実です。
確認手順:
- 対象の要素を右クリックし、「検証(Inspect)」を開く。
- Elementsパネルで親要素(
display: flexを指定した要素)を選択する。 - Stylesタブや Computedタブで、
align-itemsや実際に適用されているボックスサイズ(Box Model)を確認する。 - Layoutパネル(または要素のホバー表示)で、Flexboxの主軸・交差軸の方向や、各アイテムに適用されている実際のピクセル数を確認する。
これにより、意図したスタイルが上書きされていないか、どのプロパティが高さに影響しているかを視覚的に突き止めることができます。
WEBCOACH|副業・フリーランス特化型のオンラインWebデザインスクールFlexboxで高さを揃えない・一部だけ揃える方法

Flexboxはデフォルトで高さを揃える方向に動作しますが、デザインの要件によっては「高さを一律に揃えたくない」「特定のカードやボタンだけ高さを個別調整したい」というケースがあります。親要素全体の振る舞いを変更するか、個別のアイテムに対して上書き指定を行うことで、柔軟なコントロールが可能です。
align-items: flex-startで各要素の高さを内容に合わせる
横並びにした要素の高さが一番高いものに自動で引き伸ばされる(stretch)のを防ぎ、それぞれのコンテンツ量に応じた個別の高さにしたい場合は、親要素の align-items プロパティに flex-start(または flex-end、center)を指定します。
これにより、子要素は交差軸方向(垂直方向)へ引き伸ばされなくなり、それぞれの内容の高さがそのまま保持されます。
以下は、カードの高さの一括揃えを解除し、内容量に応じた高さにする実装例です。
<div class="card-container-natural">
<div class="card">
<h3>短いタイトル</h3>
<p>1行のテキスト。</p>
</div>
<div class="card">
<h3>長いタイトル</h3>
<p>こちらは複数の行にわたる長いテキストが記述されているカードのコンテンツになります。高さが内容に応じて変わります。</p>
</div>
</div>
.card-container-natural {
display: flex;
gap: 20px;
align-items: flex-start; /* 高さを揃えず、上部を基準にそれぞれの内容量に合わせる */
}
.card {
flex: 1; /* 幅は均等に配分する */
background-color: #f8f9fa;
border: 1px solid #dee2e6;
padding: 20px;
border-radius: 8px;
}
この設定では、.card 自体は flex: 1 によって横幅が均等に配分されますが、高さは align-items: flex-start の効果によって引き伸ばされず、各カードのテキスト量に応じた個別の高さになります。
align-selfで特定の要素だけ配置を変更する
親要素の align-items で全体的な高さを揃えつつ、「特定のカードや要素だけは高さを揃えずに上に配置したい」「一部のアイテムだけ挙動を変えたい」という場合は、その対象となる子要素に直接 align-self プロパティを指定します。
align-self は、親要素の align-items の設定よりも優先して個別の配置や高さを制御できるため、一部分だけ例外的なレイアウトを作りたい場合に重宝します。
以下は、全体は高さを揃えつつ、特定のカードだけ上部に配置し高さを個別にする実装例です。
<div class="card-container">
<div class="card">
<h3>通常のカード</h3>
<p>高さが自動的に揃うカードです。</p>
</div>
<div class="card special-card">
<h3>特定のカード</h3>
<p>このカードだけ高さを揃えず、内容に合わせる。</p>
</div>
<div class="card">
<h3>通常のカード</h3>
<p>高さが自動的に揃うカードです。</p>
</div>
</div>
.card-container {
display: flex;
gap: 20px;
align-items: stretch; /* 基本はすべての高さを揃える */
}
.card {
flex: 1;
background-color: #f8f9fa;
border: 1px solid #dee2e6;
padding: 20px;
border-radius: 8px;
}
/* 特定の要素だけstretchの適用を外す */
.special-card {
align-self: flex-start; /* この要素だけ交差軸の始点に寄り、高さが中身に依存する */
background-color: #fff3cd; /* 視覚的に区別するための背景色 */
}
このように align-self を活用すれば、Flexboxの「基本的に高さを揃える」という利便性を維持しながら、デザイン上の細かい調整や例外的な配置を柔軟に行うことができます。
まとめ
Flexboxを用いた高さの制御は、横並びや縦並び、そして複雑なカードのレイアウトを実現するうえで欠かせないテクニックです。本記事で解説した重要なポイントを振り返ります。
Flexboxの挙動は、主軸と交差軸の概念や stretch の仕組みを正しく理解することで、思い通りのレイアウトにコントロールできるようになります。実際の制作現場で高さのズレやレイアウト崩れに直面した際は、本記事の内容を参考に一つひとつのプロパティと親子の関係性を検証してみてください。


