flexboxを使うと、縦、横いずれかの方向でのレイアウト設計が簡便にできます。各itemを自動で調節、ページ画面に配置してくれるからです。しかし、意図通りに表示するには、flexboxの各プロパティの仕様を知る必要があります。
flexboxの表示崩れと解決策
flex containerの仕様
画像の表示崩れ
画像を親要素(flex container)の直下に置いてみます。
<div class="parent">
<img class="child-img" src="画像のurl"> /* div直下のitem */
<p class="child-text">文言1</p>
<p class="child-text">文言2</p>
<p class="child-text">文言3</p>
</div>
.parent {
display: flex; /* flex container(親)を設定 以下親側でのデザイン指定 */
justify-content: space-around; /* 余白付き両端揃え */
background: #efffff; /* flex(親)範囲の説明用につけた仮の色 */
}
文言1
文言2
文言3
子要素(item)にデザインが施されていないため、子要素は内容だけしか表示されません。textの子要素にデザインを与えます。
.child-text {
padding: 4px 5px; /* 余白 */
height: 100%; /* %設定で、textの高さに合わせます*/
width: 6em; /* 6文字分の幅 */
line-heght: 1.25; /* 改行幅を半分に設定 */
background: #fff; /* 説明用色付け */
}
ガソリンスタンドに寄り、燃料補給です。
大分、夜も更けてきました。
後、少しでホテルに到着です。
flex boxは、画面の大きさに応じて自動的に表示を調整してくれるレスポンシブデザインに使える機能です。親要素(flex container)の表示幅をおよそ半分にしてみます。
.parent {
~ /* 重複分省略 */
width: 310px; /* 幅を狭くします */
background: #fff; /* 通常の背景として白に */
}
この表示の乱れは、
親要素のフレックコンテナーの影響に
によるものです
flex boxは、主軸(ここでは横)方向については、最低限の幅(画像の横幅/文言では最低1文字分の幅)は確保されて維持されますが、親の直下となるimg(置換要素)の交差軸方向(縦)は親要素の大きさ(高さ)まで自動で引き延ばされます。このため、画像に歪みがでます。
解決方法
これを補正するには、img要素に max-height : 画像の高さ; を指定します。
.child-img {
max-height: 150px; /* 高さは最大でも150pxに */
}
交差軸方向(縦)の大きさ(高さ)が
補正され、絵の縦横比が
正しく表示されています
<p>要素の中にimgを置く
<div>要素の中に直接img要素を置かず、<p>で挟みます。通常はこの方が普通の設定です。
<div class="parent">
<p class="child-img"><img src="画像のurl"></p> /* wrapper */
~ /* 他のitem記述省略 */
</div>

画像も
他の要素とつり合うように、
自動で縮小されます。
画像の縦横比は維持されましたが、画像そのものが縮小しています。
画像だけでなく、文言も6文字表示のはずですが、幅が縮小され一行の文字数が減少しています。画像や縮小してほしくないitemがあれば、個別に設定する必要があります。
flexリファレンスの仕様
一括指定と個別指定の落とし穴
推奨は、可読性からか、一括指定です。
個別指定 flex-basis: 基本サイズ ; を一括指定 fle: 基本サイズ ; 、値の省略で指定します。
.child-img {
flex: 200px; /* widthと置き換え */
}
.child-text {
padding: 4px 5px; /* 余白 */
height: 100%;
flex: 6em; /* 6文字分の幅を確保 */
line-heght: 1.25;
background: #fff;
}

おや、
変化
なし。
値を省略できるのは、自動設定の値で良い時だけです。参照 flexリファレンス
伸長係数(flex-grow)や縮小係数(flex-shrink)は一括指定を使うと、どちらも1(伸び縮みする)が指定されます。結果、親要素の大きさに合わせ自動的に拡大縮小が行われます。
一括指定では、意図に合う値を正しく指定します。
.child-img {
flex: 0 0 200px; /* 拡縮しないで固定 */
}
.child-text {
padding: 4px 5px;
height: 100%;
flex: 0 0 6em; /* 6文字分の幅を絶対保持 */
line-heght: 1.25;
}

ガソリンスタンドに寄り、燃料補給です。
大分、夜も更けてきました。
後、少しでホテルに到着です。
画面に表示されるのは、親要素の大きさまでです。
itemの大きさを固定した場合、その合計が親であるflex containerの大きさを超えてしまうと、表示されなくなります。表示を優先するためにflexboxは、itemの幅を自動で調節するのです。
containerから溢れたitemも表示させる方法が、flex container(親)に用意されています。
itemを折り返して表示させる
flex-wrap
主軸が横(行)の場合は新しい行を、縦(列)の場合は新しい列を増やしてitemを(残らず)表示させます。折り返しの設定です。
構文と値
nowrap
:初期値。折り返しはしない。
wrap
:折り返しをする。
.parent {
~ /* 重複分省略 */
flex-wrap: wrap; /* 改行設定 */
}

ガソリンスタンドに寄り、燃料補給です。
大分、夜も更けてきました。
後、少しでホテルに到着です。
折り返し(改行)によって、残りのitemも表示されるようになりました。これでも良いのですが、折り返し後のitemのレイアウトが気になるかも知れません。
.child-text {
padding: 4px 5px;
height: 100%;
flex: 1 1 6em; /* 伸び縮みの余地があれば収縮可 */
line-heght: 1.25;
}

ガソリンスタンドに寄り、燃料補給です。
大分、夜も更けてきました。
後、少しでホテルに到着です。
flex containerの幅にそれぞれのitemが自動で大きさを変え、収めることができました。
flexboxの利点は、自動でitemの大きさを柔軟に変える点にあります。この機能を活かしたレイアウト設計をすることが大切です。各リファレンスの特性を理解し、使いこなしてみましょう。