CSSでボックスや画像の高さを揃えるには?Flexboxの活用テクニック
2021/05/19
WEBデザインでは、ボックスや画像などの要素を並列させたい場面が多々あります。
しかし、隣同士の要素の高さが不釣り合いの場合、下図のようにアンバランスな印象を与えてしまいます。
それぞれheight
を同じ値にすれば解決しますが、要素内のコンテンツ(テキスト)を限られた高さの中に収めなければなりません。
あるいは、コンテンツ量に合わせてheight
の値をいちいち調整しても良いですが…面倒くさいですよね。
要素の高さをコンテンツの量に合わせて自動的に整えることができれば、コーディング&レイアウトがしやすくなるでしょう。
今回は、並列するボックスや画像の高さを一発で揃える方法を解説したいと思います。
もくじ
1.Flexboxでボックスの高さを揃える
まず、div等のブロック要素を横並びにする時の手法として、float
やdisplay: inline-block
がお馴染みですよね。
しかし、これらでボックスの高さ(上端から下端まで)を合わせるには、他のプロパティと組み合わせてコーディングする必要があります。
そこでおすすめしたいのが「Flexbox」と呼ばれるCSSのレイアウト手法です。
Flexboxは、ボックスを横並びにしつつ、高さも揃えるのに有効です。
例えば、以下のように親要素(parent_box)内の3つのボックスを並列させたい場合があるとします。
1 2 3 4 5 |
<div class="parent_box"> <div>ブロック要素を横並びにしたいなぁ。</div> <div>並列させた要素の高さも揃えたいなぁ</div> <div>でも、floatやinline-blockでは限界があるなぁ。やっぱり全ての要素のheightを同じ値に指定するしかないかぁ??</div> </div> |
あえて各ボックスの文字数に差をつけてみました。
この状態で同じ幅を指定している場合、各ボックスの高さは不揃いになります。
しかし、Flexboxを使えば、一発でボックスの高さが揃います。
親要素(parent_box)のdisplay
プロパティの値を、以下のように変更してみてください。
1 2 3 4 5 6 7 8 9 10 |
.parent_box { display: flex; } .parent_box div { width: 150px; padding: 10px; margin-right: 5px; background: #ffc0cb; } |
すると、ボックスを横並びにしつつ、最も内容量が大きいボックスの高さに、他のボックスの高さが揃います。
親要素のスタイルにdisplay: flex
の一行を加えるだけなので、非常に便利です。
ただし、対応ブラウザには注意です。
大半のブラウザの最新版ではFlexboxの対応が進んでいますが、古いバージョンでは非対応、あるいはベンダープレフィックスが必要になるケースがあります。
(参考)Flexboxのブラウザ対応状況一覧(Can I use)
可能な限り様々な環境に対応できるよう、ベンダープレフィックスを追記しておくと良いでしょう。
1 2 3 4 5 |
.parent_box { display: -webkit-box; display: -ms-flexbox; display: flex; } |
2.ボックスの「中身」の高さを合わせるには?
前章では、横並びのボックスの高さを揃える方法について解説しました。
では、横並びのボックスの「中身」の高さを揃えるにはどうしたら良いでしょう?
例えば、下図のように「見出し」「説明文」「メタ情報(カテゴリー名・更新日)」で構成されたボックスがあるとします。
しかし、説明文のテキスト量によってメタ情報の位置が定まらず、見栄えがあまりよろしくありません。
一方、下図のように説明文の高さを揃えることができれば、メタ情報をブロックの下端に配置することができます。
説明文の要素に対してheight
を指定しても良いですが、テキスト量が上限を超えてしまうとレイアウトを崩してしまう恐れがあります。
そこで、前章と同様にflex
を使ってみましょう。
まずは、HTMLを確認してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<div class="parent_box"> <div class="child_box"> <h2>見出し</h2> <p class="description">説明文</p> <p>メタ情報</p> </div> <div class="child_box"> <h2>見出し</h2> <p class="description">説明文</p> <p>メタ情報</p> </div> </div> |
まず、.parent_box
内の各ボックス(.child_box
)を水平配置し、また.child_box
内の「見出し」「説明文」「メタ情報」を垂直に並べてみたいと思います。
flex
単体では水平軸に並列されますが、以下のようにflex-direction
プロパティを追記することで主軸の方向を調整できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
.parent_box { width: 800px; display: flex; /* 子要素を横並べ */ justify-content: space-around; } .child_box { width: 350px; padding: 10px; background: #b0c4de; display: flex; flex-direction: column; /* 子要素を縦並べ */ } .description { flex-grow: 1; /* 余白の割り当て */ } |
説明文(.description
)のスタイルに追加したflex-grow
は、ボックス内の余白を割り当てるプロパティです。
「見出し」「メタ情報」には指定せず、「説明文」にだけ全ての余白を割り当てることで、ボックス内での高さが均等になります。
ボックス自体の横並びもFlexboxで指定しているため、説明文のテキスト量の上限を気にせずに「ボックスの高さ」「ボックスの中身の高さ」を揃えることができます。
3.画像の高さを縦横比を維持したまま揃えたい
Flexboxを使えば、画像の高さを揃えることも簡単です。
例えば、以下のような幅・高さが同じでない画像を横並びにすると、当然ですが、高さは揃いません。
では、これらの画像をブロック要素で囲み、Flexboxを適用してみるとどうなるでしょうか?
1 2 3 4 |
<div class="box"> <img src="./sample01.jpg"> <img src="./sample02.jpg"> </div> |
1 2 3 4 5 |
.box { display: flex; width: 600px; justify-content: space-around; } |
ついでに画像を囲む親要素には枠を指定し、justify-content
で画像を均等に配置するよう試みています。
結果は上図のように画像の高さを揃えることに成功しました。
しかし、ブロックの高さに強制的にリサイズされるため、より小さな画像(左のイメージ)が縦横比に関係なく引き伸ばされてしまっています。
では、縦横比を揃えつつ、画像の高さを揃えるにはどうしたら良いのでしょうか?
そんな時に有効なのがobject-fit
プロパティです。
以下のようにブロック内のimg
に対してobject-fit: cover
を追記してみてください。
1 2 3 4 5 6 7 8 9 |
.box { width: 600px; display: flex; justify-content: space-around; } .box img { object-fit: cover; } |
object-fit: cover
を指定すると、縦横比を維持したまま画像の領域に収まるようリサイズされ、また領域からハミ出た部分はトリミング(切り抜き)されます。
結果は以下の通りで、ちょっと違いがわかりにくいですが、縦横比を維持したままのリサイズに成功しています。
ちなみに、object-fit
を活用すれば高さだけでなく、幅に固定値を指定した場合にも縦横比は崩れません。
例えば、画像を正方形にリサイズして横に並べたい時などにも有効です。
1 2 3 4 5 6 7 8 9 10 11 |
.box { width: 600px; display: flex; justify-content: space-around; } .box img { width: 200px; height: 200px; object-fit: cover; } |
このように、object-fit
はWEBデザインでは汎用性の高いプロパティなので、覚えておくと便利です。
まとめ
今回は、横に並べたボックスや画像の高さを揃えるテクニックについて解説しました。
div
等のブロック要素で描画したボックスを高さを揃えながら並列させるにはFlexbox(display: flex
)が有効です。
また、ボックス内の要素の高さを均等にするにはflex-grow
を応用して、残りの余白を割り当てると良いでしょう。
画像の場合は、単純なリサイズだけでなく縦横比にも気を配る必要がありました。
object-fit
を使うことで、縦横比を崩さずに高さを揃えることができます。