スキップしてメイン コンテンツに移動

display:flexで画像が潰れるとか膨らむなんて場合の対処法

ブログの人気の投稿の表示で画像と文章をCSSのdisplay:flexで横並びにしようとしたら上手く行かなくて参った。行毎に画像の大きさが異様に変わったり、スペースに合わなくて無駄な隙間が増えるかスペースが広がり過ぎて慌てるばかりだった。画像が潰れるとしか呼べない。あるいは縮んだり、膨らんだりして大変だったけど、しかし何とか考え通りの表示を果たしたので、覚え書きというか、どうすれば上手く行ったかの対処法を纏めておきたい。

フレックスボックスと画像を分けて捉える

失敗の原因として気付いたのは画像を親ボックスに入れて画像の大きさだけを指定して文章と合わせようとした。するとフレックスボックスに対しては画像の親ボックスと文章の大きさが変化することになるので、画像自体の大きさが影響しなくなる。CSSのwidthなどで、画像の横幅を変えようとしても親ボックスの大きさは変わらず、文章との比率も定まらない。

画像を親ボックスに入れる場合は親ボックスのサイズを取らないと横並びの文章の長さ(フレックスボックスでの文章のスペース)に応じて画像の大きさが親ボックスと共に変化するし、潰れる嵌めにも陥る。

画像を親ボックスに入れて文章と揃える方法

フレックスボックスで固有の親ボックスに入れた画像を潰さないためには親ボックスのサイズを固定するというか、文章との割合を揃えるように指定する。

画像の親ボックスに横幅のwidthなどと共にflex-shrink:0を指定するとフレックスボックスの子要素として伸縮しなくなるので、横並びの文章が長くても短くても(フレックスボックスでのスペースが広くても狭くても)変わらなくなる。

画像の親ボックスと文章の四対六の横並びの例

窓辺に置かれた白いフクシア
窓辺に置かれた白いフクシア

HTML

<figure class="flexbox">
<div class="parentbox">
<img src="/fuchsia.jpg">
</div>
<figcaption>
窓辺に置かれた白いフクシア
</figcaption>
</figure>

CSS

.flexbox {display:flex;column-gap:.5em}
.parentbox {flex-shrink:0;width:40%}
.parentbox img {width:100%;height:auto}
.flexbox figcaption {width:100%;background-color:#dda0dd}

フレックスボックスの子要素のflex-shrink:0はショートハンドのflexでflex-grow(取る比率)とflex-basis(占める大きさ)と一緒に指定する仕方ならばnone(全く伸縮しない)のときにも0になる。

サンプルの{flex-shrink:0;width:40%}{flex:0 0 40%}{flex:none;width:40%}{flex:0 0 content;width:40%}と書いても同じ結果を得る。

またはフレックスボックスの子要素の大きさを指定するflex-basisとwidthを置き換えて{flex-shrink:0;flex-basis:40%}{flex:0 0 40%}と書いても同じ結果を得る。

flexの値を複数に分けると一つ目はflex-growで、これは0以外の値にすると他のコンテンツとの関係で空きができたときに大きさが固定されない可能性がある。

画像の親ボックスと文章などを揃える際の注意点としてflex-shrink:0と共に画像の親ボックスの大きさを指定するだけでは画像と文章の横並びの割合を十分に纏めることはできない。画像がもっと大きい場合は親ボックスの範囲内に収まるけれどももっと小さい場合に空きができて潰れてしまう。

どんな大きさの画像でも親ボックスにぴったり合わせて表示するためには画像の横幅もwidth:100%と指定する必要がある。

画像をそのままで文章と揃える方法

特に何もなければフレックスボックスの画像を親ボックスに入れる必要はない。文章と横並びに表示するにはもっと簡単で良いと思うし、画像をそのままで子要素として扱う方が基本的なマークアップだ。

気がかりなのは横並びの文章との割合を一定に保てるかどうか。さもないとバランスが崩れて画像が縮んだり、膨らんだりしてしまう。

フレックスボックスの子要素の伸縮を止めるflex-shrink:0を画像自体にしっかりかけることが何よりも重要だ。その上で、フレックスボックスの子要素のスペースを決めるflex-basisか画像の横幅のwidthなどで表示する大きさを指定する。

画像自体と文章の四対六の横並びの例

窓辺に置かれた白いフクシア
窓辺に置かれた白いフクシア

HTML

<figure class="flexbox">
<img src="/fuchsia.jpg">
<figcaption>
窓辺に置かれた白いフクシア
</figcaption>
</figure>

CSS

.flexbox {display:flex;column-gap:.5em}
.flexbox img {flex-shrink:0;width:40%;height:100%}
.flexbox figcaption {width:100%;background-color:#dda0dd}

フレックスボックスの子要素のflex-shrink:0はショートハンドのflexでflex-grow(取る比率)とflex-basis(占める大きさ)と一緒に指定する仕方ならばnone(全く伸縮しない)のときにも0になる。

サンプルの{flex-shrink:0;width:40%}{flex:0 0 40%}{flex:none;width:40%}{flex:0 0 content;width:40%}と書いても同じ結果を得る。

またはフレックスボックスの子要素の大きさを指定するflex-basisとwidthを置き換えて{flex-shrink:0;flex-basis:40%}{flex:0 0 40%}と書いても同じ結果を得る。

flexの値を複数に分けると一つ目はflex-growで、これを0以外の値にすると他のコンテンツとの関係で空きができたときに大きさが固定されない可能性がある。

画像を実際の大きさよりも小さく表示する場合は画像に最大の横幅のmax-widthや最大の縦幅のmax-heightを指定する必要がある。

画像と文章などを揃える際の注意点としてflex-shrink:0と共に画像の横幅を指定するだけでは縦幅がスペース一杯に伸びて表示されてしまうかも知れない。他のコンテンツの縦幅が画像よりも増えた場合に生じるけれどもdisplay:flexの子要素の縦方向の位置取りの初期値がstretch(引き伸ばす)になっているためだ。

サンプルでは画像に縦幅もheight:100%と指定して実際の大きさよりも伸びないようにしている。その他にフレックスボックスにalign-itemsか画像にalign-selfで縦方向の位置取りに初期値のstretch以外の値を入れると大丈夫だ。

参考:Flexboxを使う時に覚えておきたい!固定幅と可変幅を組み合わせたレイアウトを簡単に実装する方法

コメント