5

I have a div using flexbox to center its items. Inside this div I have 3 elements, one of them is an image.

<div id="flex-container">
    <div id="container1"></div>
    <img src="#" alt="">
    <div id="container2"></div>
</div>

#container1 and #container2 have their own height, and the img should use the remaining height inside #flex-container.

This snippet works on Firefox, but doesn't work in Chrome. (jsfiddle)

#flex-container{
  height: 300px;
  width: 500px;
  display: flex;
  display: -webkit-flex;
  flex-flow: column nowrap;
  -webkit-flex-flow: column nowrap;
  justify-content: center;
  -webkit-justify-content: center;
  align-items: center;
  -webkit-align-items: center;
  border: 5px solid black;
}

#container1, #container2{
  height: 100px;
  width: 300px;
  background: orange;
  flex: 1 0 auto;
  -webkit-flex: 1 0 auto;
}
<div id="flex-container">

  <div id="container1">300x100 px</div>

  <img src="http://i.imgur.com/RRUe0Mo.png" alt="">

  <div id="container2">300x100 px</div>

</div>

Chrome needs -webkit- prefixes for flexbox, but the issue doesn't seem to be this.

What can be happening? Is a browser bug or I'm forgetting something?

Gerard Reches
  • 3,048
  • 3
  • 28
  • 39

1 Answers1

14

There are two problems you need to overcome:

Firefox solves them both on its own, but Chrome needs assistance.

Problem #1

The first problem is that flex items, by default, cannot be smaller than their content. An initial setting on flex items is min-height: auto.

Therefore, a flex item with a replaced element, like an image, will default to the inherent size of the image. The item cannot be made smaller, unless you override the initial setting (use min-height: 0).

#flex-container {
  height: 300px;
  width: 500px;
  display: flex;
  flex-flow: column nowrap;
  justify-content: center;
  align-items: center;
  border: 5px solid black;
}
#container1, #container2 {
  height: 100px;
  width: 300px;
  background: orange;
  flex: 1 0 auto;
}
img { min-height: 0; } /* NEW */
<div id="flex-container">

  <div id="container1">300x100 px</div>

  <img src="http://i.imgur.com/RRUe0Mo.png" alt="">

  <div id="container2">300x100 px</div>

</div>

A complete explanation of this issue can be found here:


Problem #2

Then you hit the second problem: keeping the aspect ratio. This is a common problem in flex containers. One option is to define a height for the image:

#flex-container {
  height: 300px;
  width: 500px;
  display: flex;
  flex-flow: column nowrap;
  justify-content: center;
  align-items: center;
  border: 5px solid black;
}
#container1, #container2 {
  height: 100px;
  width: 300px;
  background: orange;
  flex: 1 0 auto;
}
img { min-height: 0; height: 100px; } /* NEW */
<div id="flex-container">

  <div id="container1">300x100 px</div>

  <img src="http://i.imgur.com/RRUe0Mo.png" alt="">

  <div id="container2">300x100 px</div>

</div>
Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • I'm still not understanding exactly why the `min-height` is necessary to make it work on Chrome, but it's extensively explained on your answers, I will take another look when I can. And there is no way to shrink the image height at the same time as keeping the aspect ratio? Wrapping it inside a `div` maybe? – Gerard Reches Nov 30 '16 at 18:27
  • Yes, my linked answer provides a detailed explanation. About the aspect ratio, like I said, it's a common problem and I've seen many solutions. A `div` wrapper has worked for me before. Test it out. Cheers! – Michael Benjamin Nov 30 '16 at 18:29
  • To whom it may concern: shrinking image while maintaining aspect ratio can be done with `object-fit: contain;` CSS property. – Alexandr Zarubkin Aug 22 '18 at 13:25