flexboxでレイアウトを組んでいるとき、「隣り合う要素の高さが揃わない」という現象にぶつかったことがある人は多いと思います。原因はだいたいパターンが決まっているので、よくあるものをまとめておきます。
そもそも高さは自動で揃うのが基本
flexコンテナの子要素は、`align-items`が初期値の`stretch`であれば、本来は高さが自動で揃います。
.parent {
display: flex;
}
.child {
/* align-itemsを指定しなければ自動でstretchになり、高さが揃う */
}
「揃わない」と感じるときは、だいたい以下のどれかが原因です。
原因1: align-itemsを上書きしてしまっている
子要素側や親要素側で`align-items: flex-start`などを指定していると、stretchが効かなくなり、コンテンツ量に応じた高さになります。揃えたい場合は、余計な上書きが入っていないか確認します。
.parent {
display: flex;
align-items: flex-start; /* これがあると高さが揃わなくなる */
}
特にカードコンポーネントなどで、中身を縦方向の中央に寄せたくて`align-items: center`を指定してしまい、結果として高さが揃わなくなるケースをよく見かけます。中央寄せしたいのが「テキストだけ」なのか「カード全体」なのかを切り分けて、カード自体はstretchのままにし、中のテキストブロックだけflexにして中央寄せする、という二段構えにすると解決しやすいです。
原因2: 子要素にheightやmax-heightが個別指定されている
子要素そのものに固定の高さが指定されていると、当然そこで頭打ちになります。カード型のコンポーネントなどでありがちなので、疑わしい箇所は一度指定を外して検証してみるのが早いです。
特に、レスポンシブ対応の過程で「スマホ表示のときだけ高さを固定した」指定が、そのままPC表示にも引き継がれてしまっているケースは見落としがちです。メディアクエリの範囲を一つずつ確認するのも有効です。
原因3: 孫要素以下でflexが二重にかかっている
親はflexで揃っているのに、中の要素(画像やテキストブロック)が独自にpositionやfloatを使っていて、実質的に高さの計算から外れているケースもあります。この場合はDevToolsでボックスの実際の高さを一つずつ確認するのが確実です。
また、画像を`object-fit: cover`で高さ固定にしているつもりが、親要素の高さが不確定なまま(auto)になっていて、結局画像の実サイズに引っ張られてしまうパターンもあります。この場合は、画像を囲むラッパー側の高さをきちんとflexの中で確定させる必要があります。
原因のあたりをつけるためのチェックリスト活用
案件によっては、似たような「揃わない」相談を何度も受けることがあります。そのたびに一から原因を探すのは非効率なので、自分用にチェックリストを作って、都度そこから当てはまるものを潰していく運用にしています。原因のパターンはある程度限られているので、リスト化しておくだけで調査時間はかなり短縮できます。
原因4: gapとmarginの混在で見た目の高さがズレる
直接の「揃わない」原因ではないのですが、`gap`プロパティと子要素の`margin`を併用していると、見た目の余白が二重にかかって高さが揃っていないように見えることがあります。flexboxでの余白管理は、`gap`か`margin`のどちらかに統一しておくと、後々の混乱を防げます。
実際にあった事例
実際の案件で遭遇した例を挙げると、3列のカードレイアウトで、画像の下にタイトルと本文、その下にボタンを配置するコンポーネントがありました。ボタンの位置を各カードの一番下で揃えたかったのですが、本文の文字数がカードごとに違うため、そのままではボタンの位置がバラバラになってしまいます。
.card {
display: flex;
flex-direction: column;
}
.card__body {
flex: 1; /* 余った縦スペースを本文側に伸ばす */
}
.card__button {
/* flex: 1 の効果で、常にカードの一番下に配置される */
}
この場合は、カード自体を`flex-direction: column`にした上で、ボタンより上の要素(本文部分)に`flex: 1`を指定することで解決しました。余ったスペースを本文側が伸びて吸収してくれるので、ボタンは常にカードの一番下に揃います。「高さを揃える」と「要素の配置を揃える」は似ているようで解決方法が違うので、混同しないように気をつけています。
デバッグの基本手順
- まずコンテナに`align-items`が明示されていないか確認する
- 子要素のheight系プロパティを一時的にすべて外してみる
- それでも揃わなければ、孫要素以下のposition/floatを疑う
- gapとmarginが混在していないか、余白の指定方法を確認する
地味な作業ですが、順番に一つずつ潰していけば、大抵はどこかで原因が見つかります。焦って`!important`で無理やり高さを固定するより、まずは原因の切り分けを優先したほうが、結果的に修正がシンプルになることが多いです。
gridで解決したほうが早いケースもある
ここまでflexboxでの原因切り分けを紹介してきましたが、そもそもカードを縦横に整列させるような用途であれば、flexboxよりgridの方が向いている場合もあります。gridは行と列の概念を明示的に扱えるため、高さを揃えたい・幅も揃えたいという要件であれば、`display: grid`にして`grid-template-columns`で列数を指定するだけで、flexboxで発生しがちな高さのズレそのものが起きにくくなります。「揃わない原因を頑張って探す」より「そもそも揃うレイアウト手法に変える」という選択肢も、実務では有効な解決策のひとつです。
まとめ
flexboxの「高さが揃わない」問題は、ほとんどの場合、align-itemsの上書き・個別のheight指定・孫要素以下の独自レイアウトのどれかに原因があります。DevToolsでボックスモデルを一つずつ確認しながら、原因を機械的に潰していくのが結局いちばんの近道です。感覚だけで「なんとなくこれが怪しい」と決め打ちせず、ひとつずつ仮説を検証していく姿勢が、結果的にはいちばん早い解決につながると感じています。
この記事が参考になったら、応援クリックをお願いします


